From fd6836d5a10ab093574cb8b81edb1de8d5296bd0 Mon Sep 17 00:00:00 2001 From: Iulian Moraru Date: Tue, 16 May 2023 09:35:29 +0300 Subject: [PATCH] Backed out 10 changesets (bug 1528042) for causing build bustages on MediaDevices.cpp. Backed out changeset 04d9fa0993ab (bug 1528042) Backed out changeset a20768227ca6 (bug 1528042) Backed out changeset 94066f37c5a0 (bug 1528042) Backed out changeset cb2b433b47bd (bug 1528042) Backed out changeset d0bfd185f0e7 (bug 1528042) Backed out changeset 59b9147c85f0 (bug 1528042) Backed out changeset e864d7f810b3 (bug 1528042) Backed out changeset c0373264c89b (bug 1528042) Backed out changeset cf689822deaf (bug 1528042) Backed out changeset 0ac40a8f40a0 (bug 1528042) --- dom/base/Navigator.cpp | 8 +- dom/media/MediaDevices.cpp | 132 ++++++++-------- dom/media/MediaDevices.h | 12 -- dom/media/MediaManager.cpp | 20 ++- .../tests/mochitests/mediaStreamPlayback.js | 54 ++----- .../webrtc/tests/mochitests/mochitest.ini | 2 - .../mochitests/test_enumerateDevices.html | 51 +++--- ...est_enumerateDevices_getUserMediaFake.html | 51 +++--- .../test_enumerateDevices_iframe.html | 11 +- .../test_enumerateDevices_iframe_pre_gum.html | 22 --- .../test_enumerateDevices_legacy.html | 147 ------------------ .../test_getUserMedia_basicScreenshare.html | 9 +- .../test_getUserMedia_trackCloneCleanup.html | 8 +- .../webrtc/tests/mochitests/test_groupId.html | 13 +- modules/libpref/init/StaticPrefList.yaml | 17 -- .../meta/audio-output/__dir__.ini | 2 +- ...vices-persistent-permission.https.html.ini | 5 + ...ateDevices-returned-objects.https.html.ini | 5 + ...diaDevices-enumerateDevices.https.html.ini | 3 + .../meta/mediacapture-streams/__dir__.ini | 2 +- ...diaDevices-enumerateDevices.https.html.ini | 6 - .../MediaDevices-enumerateDevices.https.html | 110 ------------- .../mediacapture-streams/permission-helper.js | 24 --- ...eDevices-with-selectAudioOutput.https.html | 8 +- ...teDevices-persistent-permission.https.html | 2 +- ...umerateDevices-returned-objects.https.html | 7 +- .../MediaDevices-enumerateDevices.https.html | 93 +++-------- .../MediaDevices-getUserMedia.https.html | 8 - .../MediaStreamTrack-getSettings.https.html | 29 ++-- .../iframe-enumerate-pre-gum.html | 2 - .../message-enumerateddevices-pre-gum.js | 4 - 31 files changed, 207 insertions(+), 660 deletions(-) delete mode 100644 dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe_pre_gum.html delete mode 100644 dom/media/webrtc/tests/mochitests/test_enumerateDevices_legacy.html create mode 100644 testing/web-platform/meta/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html.ini create mode 100644 testing/web-platform/meta/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html.ini delete mode 100644 testing/web-platform/mozilla/meta/mediacapture-streams/MediaDevices-enumerateDevices.https.html.ini delete mode 100644 testing/web-platform/mozilla/tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html delete mode 100644 testing/web-platform/mozilla/tests/mediacapture-streams/permission-helper.js delete mode 100644 testing/web-platform/tests/mediacapture-streams/iframe-enumerate-pre-gum.html delete mode 100644 testing/web-platform/tests/mediacapture-streams/message-enumerateddevices-pre-gum.js diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 783c54effe02..85340db5dc4e 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1321,15 +1321,11 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints, NavigatorUserMediaErrorCallback& aOnError, CallerType aCallerType, ErrorResult& aRv) { MOZ_ASSERT(NS_IsMainThread()); + if (!mWindow || !mWindow->IsFullyActive()) { aRv.ThrowInvalidStateError("The document is not fully active."); return; } - GetMediaDevices(aRv); - if (aRv.Failed()) { - return; - } - MOZ_ASSERT(mMediaDevices); if (Document* doc = mWindow->GetExtantDoc()) { if (!mWindow->IsSecureContext()) { doc->SetUseCounter(eUseCounter_custom_MozGetUserMediaInsec); @@ -1343,7 +1339,7 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints, "audio and/or video is required"), __func__); } else { - sp = mMediaDevices->GetUserMedia(mWindow, aConstraints, aCallerType); + sp = MediaManager::Get()->GetUserMedia(mWindow, aConstraints, aCallerType); } RefPtr onsuccess(&aOnSuccess); RefPtr onerror(&aOnError); diff --git a/dom/media/MediaDevices.cpp b/dom/media/MediaDevices.cpp index 212717676f39..7b231e1048fb 100644 --- a/dom/media/MediaDevices.cpp +++ b/dom/media/MediaDevices.cpp @@ -98,32 +98,7 @@ already_AddRefed MediaDevices::GetUserMedia( } } } - RefPtr self(this); - GetUserMedia(owner, aConstraints, aCallerType) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [this, self, p](RefPtr&& aStream) { - if (!GetWindowIfCurrent()) { - return; // Leave Promise pending after navigation by design. - } - p->MaybeResolve(std::move(aStream)); - }, - [this, self, p](const RefPtr& error) { - nsPIDOMWindowInner* window = GetWindowIfCurrent(); - if (!window) { - return; // Leave Promise pending after navigation by design. - } - error->Reject(p); - }); - return p.forget(); -} - -RefPtr MediaDevices::GetUserMedia( - nsPIDOMWindowInner* aWindow, const MediaStreamConstraints& aConstraints, - CallerType aCallerType) { - MOZ_ASSERT(NS_IsMainThread()); bool haveFake = aConstraints.mFake.WasPassed() && aConstraints.mFake.Value(); - const OwningBooleanOrMediaTrackConstraints& video = aConstraints.mVideo; const OwningBooleanOrMediaTrackConstraints& audio = aConstraints.mAudio; bool isMicrophone = !haveFake && @@ -135,26 +110,32 @@ RefPtr MediaDevices::GetUserMedia( (video.IsBoolean() ? video.GetAsBoolean() : !video.GetAsMediaTrackConstraints().mMediaSource.WasPassed()); - RefPtr self(this); - return MediaManager::Get() - ->GetUserMedia(aWindow, aConstraints, aCallerType) + MediaManager::Get() + ->GetUserMedia(owner, aConstraints, aCallerType) ->Then( GetCurrentSerialEventTarget(), __func__, - [this, self, isMicrophone, + [this, self, p, isMicrophone, isCamera](RefPtr&& aStream) { + if (!GetWindowIfCurrent()) { + return; // Leave Promise pending after navigation by design. + } if (isMicrophone) { mCanExposeMicrophoneInfo = true; } if (isCamera) { mCanExposeCameraInfo = true; } - return StreamPromise::CreateAndResolve(std::move(aStream), - __func__); + p->MaybeResolve(std::move(aStream)); }, - [](RefPtr&& aError) { - return StreamPromise::CreateAndReject(std::move(aError), __func__); + [this, self, p](const RefPtr& error) { + nsPIDOMWindowInner* window = GetWindowIfCurrent(); + if (!window) { + return; // Leave Promise pending after navigation by design. + } + error->Reject(p); }); + return p.forget(); } already_AddRefed MediaDevices::EnumerateDevices(ErrorResult& aRv) { @@ -257,7 +238,6 @@ RefPtr MediaDevices::FilterExposedDevices( // they are exposed only when explicitly and individually allowed by the // user. } - bool legacy = StaticPrefs::media_devices_enumerate_legacy_enabled(); bool outputIsDefault = true; // First output is the default. bool haveDefaultOutput = false; nsTHashSet exposedMicrophoneGroupIds; @@ -270,17 +250,13 @@ RefPtr MediaDevices::FilterExposedDevices( if (mCanExposeMicrophoneInfo) { exposedMicrophoneGroupIds.Insert(device->mRawGroupID); } - if (!mCanExposeMicrophoneInfo && !legacy) { - dropMics = true; - } + // Reducing to one mic or cam device when not mCanExposeMicrophoneInfo + // or not mCanExposeCameraInfo is bug 1528042. break; case MediaDeviceKind::Videoinput: if (dropCams) { continue; } - if (!mCanExposeCameraInfo && !legacy) { - dropCams = true; - } break; case MediaDeviceKind::Audiooutput: if (dropSpeakers || @@ -325,23 +301,6 @@ RefPtr MediaDevices::FilterExposedDevices( return exposed; } -bool MediaDevices::CanExposeInfo(MediaDeviceKind aKind) const { - switch (aKind) { - case MediaDeviceKind::Audioinput: - return mCanExposeMicrophoneInfo; - case MediaDeviceKind::Videoinput: - return mCanExposeCameraInfo; - case MediaDeviceKind::Audiooutput: - // Assumes caller has used FilterExposedDevices() - return true; - case MediaDeviceKind::EndGuard_: - MOZ_ASSERT_UNREACHABLE("unexpected MediaDeviceKind"); - return false; - // Avoid `default:` so that `-Wswitch` catches missing enumerators at - // compile time. - } -}; - bool MediaDevices::ShouldQueueDeviceChange( const MediaDeviceSet& aExposedDevices) const { if (!mLastPhysicalDevices) { // SetupDeviceChangeListener not complete @@ -358,6 +317,22 @@ bool MediaDevices::ShouldQueueDeviceChange( // exposed by enumerateDevices() (but multiple devices are currently exposed // - bug 1528042). "devicechange" events are not queued when the number // of such devices changes but remains non-zero. + auto CanExposeNonZeroChanges = [this](MediaDeviceKind aKind) { + switch (aKind) { + case MediaDeviceKind::Audioinput: + return mCanExposeMicrophoneInfo; + case MediaDeviceKind::Videoinput: + return mCanExposeCameraInfo; + case MediaDeviceKind::Audiooutput: + return true; + case MediaDeviceKind::EndGuard_: + break; + // Avoid `default:` so that `-Wswitch` catches missing enumerators at + // compile time. + } + MOZ_ASSERT_UNREACHABLE("unexpected MediaDeviceKind"); + return false; + }; while (exposed < exposedEnd && last < lastEnd) { // First determine whether there is at least one device of the same kind // in both `aExposedDevices` and `lastExposedDevices`. @@ -369,7 +344,7 @@ bool MediaDevices::ShouldQueueDeviceChange( return true; } // `exposed` and `last` have matching kind. - if (CanExposeInfo(kind)) { + if (CanExposeNonZeroChanges(kind)) { // Queue "devicechange" if there has been any change in devices of this // exposed kind. ID and kind uniquely identify a device. if ((*exposed)->mRawID != (*last)->mRawID) { @@ -424,16 +399,37 @@ void MediaDevices::ResumeEnumerateDevices( void MediaDevices::ResolveEnumerateDevicesPromise( Promise* aPromise, const LocalMediaDeviceSet& aDevices) const { + nsCOMPtr window = GetOwner(); + auto windowId = window->WindowID(); nsTArray> infos; - bool legacy = StaticPrefs::media_devices_enumerate_legacy_enabled(); - + bool allowLabel = + aDevices.Length() == 0 || + MediaManager::Get()->IsActivelyCapturingOrHasAPermission(windowId); for (const RefPtr& device : aDevices) { - bool exposeInfo = CanExposeInfo(device->Kind()) || legacy; - bool exposeLabel = legacy ? DeviceInformationCanBeExposed() : exposeInfo; - infos.AppendElement(MakeRefPtr( - exposeInfo ? device->mID : u""_ns, device->Kind(), - exposeLabel ? device->mName : u""_ns, - exposeInfo ? device->mGroupID : u""_ns)); + nsString label; + MOZ_ASSERT(device->Kind() < MediaDeviceKind::EndGuard_); + switch (device->Kind()) { + case MediaDeviceKind::Audioinput: + case MediaDeviceKind::Videoinput: + // Include name only if page currently has a gUM stream + // active or persistent permissions (audio or video) have + // been granted. See bug 1528042 for using + // mCanExposeMicrophoneInfo. + if (allowLabel || Preferences::GetBool( + "media.navigator.permission.disabled", false)) { + label = device->mName; + } + break; + case MediaDeviceKind::Audiooutput: + label = device->mName; + break; + case MediaDeviceKind::EndGuard_: + break; + // Avoid `default:` so that `-Wswitch` catches missing + // enumerators at compile time. + } + infos.AppendElement(MakeRefPtr(device->mID, device->Kind(), + label, device->mGroupID)); } aPromise->MaybeResolve(std::move(infos)); } @@ -788,10 +784,6 @@ void MediaDevices::EventListenerAdded(nsAtom* aType) { SetupDeviceChangeListener(); } -bool MediaDevices::DeviceInformationCanBeExposed() const { - return mCanExposeCameraInfo || mCanExposeMicrophoneInfo; -} - JSObject* MediaDevices::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { return MediaDevices_Binding::Wrap(aCx, this, aGivenProto); diff --git a/dom/media/MediaDevices.h b/dom/media/MediaDevices.h index 6f313bc8b42c..fa6a11c8fba9 100644 --- a/dom/media/MediaDevices.h +++ b/dom/media/MediaDevices.h @@ -11,7 +11,6 @@ #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/UseCounter.h" #include "mozilla/dom/BindingDeclarations.h" -#include "mozilla/dom/MediaDeviceInfoBinding.h" #include "nsCOMPtr.h" #include "nsID.h" #include "nsISupports.h" @@ -24,7 +23,6 @@ namespace mozilla { class LocalMediaDevice; class MediaDevice; class MediaMgrError; -class DOMMediaStream; template class MozPromise; @@ -43,8 +41,6 @@ struct AudioOutputOptions; class MediaDevices final : public DOMEventTargetHelper { public: - using StreamPromise = - MozPromise, RefPtr, true>; using SinkInfoPromise = MozPromise, nsresult, true>; explicit MediaDevices(nsPIDOMWindowInner* aWindow); @@ -62,10 +58,6 @@ class MediaDevices final : public DOMEventTargetHelper { const MediaStreamConstraints& aConstraints, CallerType aCallerType, ErrorResult& aRv); - RefPtr GetUserMedia(nsPIDOMWindowInner* aWindow, - const MediaStreamConstraints& aConstraints, - CallerType aCallerType); - already_AddRefed EnumerateDevices(ErrorResult& aRv); already_AddRefed GetDisplayMedia( @@ -111,14 +103,10 @@ class MediaDevices final : public DOMEventTargetHelper { RefPtr aExposedDevices) const; RefPtr FilterExposedDevices( const MediaDeviceSet& aDevices) const; - bool CanExposeInfo(MediaDeviceKind aKind) const; bool ShouldQueueDeviceChange(const MediaDeviceSet& aExposedDevices) const; void ResolveEnumerateDevicesPromise( Promise* aPromise, const LocalMediaDeviceSet& aDevices) const; - // See https://www.w3.org/TR/mediacapture-streams/#device-information-exposure - bool DeviceInformationCanBeExposed() const; - nsTHashSet mExplicitlyGrantedAudioOutputRawIds; nsTArray> mPendingEnumerateDevicesPromises; // Set only once, if and when required. diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index f637c1cc38cc..969553beb3b3 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -1869,8 +1869,15 @@ RefPtr MediaManager::EnumerateRawDevices( Maybe speakers; RefPtr devices = new MediaDeviceSetRefCnt(); - // Enumerate microphones first, then cameras, then speakers, since the - // enumerateDevices() algorithm expects them listed in that order. + if (hasVideo) { + videoBackend = hasFakeCams ? fakeBackend : realBackend; + MediaDeviceSet videos; + LOG("EnumerateRawDevices Task: Getting video sources with %s backend", + videoBackend == fakeBackend ? "fake" : "real"); + GetMediaDevices(videoBackend, aVideoInputType, videos, + videoLoopDev.get()); + devices->AppendElements(videos); + } if (hasAudio) { audioBackend = hasFakeMics ? fakeBackend : realBackend; MediaDeviceSet audios; @@ -1885,15 +1892,6 @@ RefPtr MediaManager::EnumerateRawDevices( } devices->AppendElements(audios); } - if (hasVideo) { - videoBackend = hasFakeCams ? fakeBackend : realBackend; - MediaDeviceSet videos; - LOG("EnumerateRawDevices Task: Getting video sources with %s backend", - videoBackend == fakeBackend ? "fake" : "real"); - GetMediaDevices(videoBackend, aVideoInputType, videos, - videoLoopDev.get()); - devices->AppendElements(videos); - } if (hasAudioOutput) { MediaDeviceSet outputs; MOZ_ASSERT(realBackend); diff --git a/dom/media/webrtc/tests/mochitests/mediaStreamPlayback.js b/dom/media/webrtc/tests/mochitests/mediaStreamPlayback.js index 44c1c78ea093..ba644390d6bc 100644 --- a/dom/media/webrtc/tests/mochitests/mediaStreamPlayback.js +++ b/dom/media/webrtc/tests/mochitests/mediaStreamPlayback.js @@ -175,9 +175,9 @@ function addLoadEvent() {} /* import-globals-from /testing/mochitest/tests/SimpleTest/SimpleTest.js */ /* import-globals-from head.js */ -const scriptsReady = Promise.all( +var scriptsReady = Promise.all( ["/tests/SimpleTest/SimpleTest.js", "head.js"].map(script => { - const el = document.createElement("script"); + var el = document.createElement("script"); el.src = script; document.head.appendChild(el); return new Promise(r => (el.onload = r)); @@ -189,12 +189,7 @@ function createHTML(options) { } async function runTest(testFunction) { - await Promise.all([ - scriptsReady, - SpecialPowers.pushPrefEnv({ - set: [["media.navigator.permission.fake", true]], - }), - ]); + await scriptsReady; await runTestWhenReady(async (...args) => { await testFunction(...args); await noGum(); @@ -203,39 +198,22 @@ async function runTest(testFunction) { // noGum - Helper to detect whether active guM tracks still exist. // -// Note it relies on the permissions system to detect active tracks, so it won't -// catch getUserMedia use while media.navigator.permission.disabled is true -// (which is common in automation), UNLESS we set -// media.navigator.permission.fake to true also, like runTest() does above. +// It relies on the fact that, by spec, device labels from enumerateDevices are +// only visible during active gum calls. They're also visible when persistent +// permissions are granted, so turn off media.navigator.permission.disabled +// (which is normally on otherwise in our tests). Lastly, we must turn on +// media.navigator.permission.fake otherwise fake devices don't count as active. async function noGum() { + await pushPrefs( + ["media.navigator.permission.disabled", false], + ["media.navigator.permission.fake", true] + ); if (!navigator.mediaDevices) { // No mediaDevices, then gUM cannot have been called either. return; } - const mediaManagerService = Cc[ - "@mozilla.org/mediaManagerService;1" - ].getService(Ci.nsIMediaManagerService); - - const hasCamera = {}; - const hasMicrophone = {}; - mediaManagerService.mediaCaptureWindowState( - window, - hasCamera, - hasMicrophone, - {}, - {}, - {}, - {}, - false - ); - is( - hasCamera.value, - mediaManagerService.STATE_NOCAPTURE, - "Test must leave no active camera gUM tracks behind." - ); - is( - hasMicrophone.value, - mediaManagerService.STATE_NOCAPTURE, - "Test must leave no active microphone gUM tracks behind." - ); + const [device] = await navigator.mediaDevices.enumerateDevices(); + if (device) { + is(device.label, "", "Test must leave no active gUM streams behind."); + } } diff --git a/dom/media/webrtc/tests/mochitests/mochitest.ini b/dom/media/webrtc/tests/mochitests/mochitest.ini index b0a17e137f97..1bbe2bfb8335 100644 --- a/dom/media/webrtc/tests/mochitests/mochitest.ini +++ b/dom/media/webrtc/tests/mochitests/mochitest.ini @@ -12,7 +12,6 @@ support-files = stats.js templates.js test_enumerateDevices_iframe.html - test_enumerateDevices_iframe_pre_gum.html test_getUserMedia_permission_iframe.html NetworkPreparationChromeScript.js blacksilence.js @@ -43,7 +42,6 @@ skip-if = scheme=http [test_enumerateDevices.html] [test_enumerateDevices_getUserMediaFake.html] -[test_enumerateDevices_legacy.html] [test_enumerateDevices_navigation.html] skip-if = true # Disabled because it is a racy test and causes timeouts, see bug 1650932 [test_fingerprinting_resistance.html] diff --git a/dom/media/webrtc/tests/mochitests/test_enumerateDevices.html b/dom/media/webrtc/tests/mochitests/test_enumerateDevices.html index 48bec0006a48..a399a83aebdb 100644 --- a/dom/media/webrtc/tests/mochitests/test_enumerateDevices.html +++ b/dom/media/webrtc/tests/mochitests/test_enumerateDevices.html @@ -11,12 +11,9 @@ createHTML({ title: "Run enumerateDevices code", bug: "1046245" }); Tests covering enumerateDevices API and deviceId constraint. Exercise code. */ -async function mustSucceedWithStream(msg, f) { +async function mustSucceed(msg, f) { try { - const stream = await f(); - for (const track of stream.getTracks()) { - track.stop(); - } + await f(); ok(true, msg + " must succeed"); } catch (e) { is(e.name, null, msg + " must succeed: " + e.message); @@ -35,12 +32,10 @@ async function mustFailWith(msg, reason, constraint, f) { } } -const gUM = c => navigator.mediaDevices.getUserMedia(c); +var gUM = c => navigator.mediaDevices.getUserMedia(c); -const kinds = ["videoinput", "audioinput", "audiooutput"]; - -function validateDevice({kind, label, deviceId, groupId}) { - ok(kinds.includes(kind), "Known device kind"); +var validateDevice = ({kind, label, deviceId, groupId}) => { + ok(kind == "videoinput" || kind == "audioinput", "Known device kind"); is(deviceId.length, 44, "deviceId length id as expected for Firefox"); ok(label.length !== undefined, "Device label: " + label); isnot(groupId, "", "groupId must be present."); @@ -49,24 +44,20 @@ function validateDevice({kind, label, deviceId, groupId}) { runTest(async () => { await pushPrefs(["media.navigator.streams.fake", true]); - // Validate enumerated devices after gUM. - for (const track of (await gUM({video: true, audio: true})).getTracks()) { - track.stop(); - } + // Validate enumerated devices. let devices = await navigator.mediaDevices.enumerateDevices(); ok(devices.length, "At least one device found"); - const jsoned = JSON.parse(JSON.stringify(devices)); + let jsoned = JSON.parse(JSON.stringify(devices)); is(jsoned[0].kind, devices[0].kind, "kind survived serializer"); is(jsoned[0].deviceId, devices[0].deviceId, "deviceId survived serializer"); - for (const device of devices) { + for (let device of devices) { validateDevice(device); - if (device.kind == "audiooutput") continue; // Test deviceId constraint let deviceId = device.deviceId; let constraints = (device.kind == "videoinput") ? { video: { deviceId } } : { audio: { deviceId } }; - for (const track of (await gUM(constraints)).getTracks()) { + for (let track of (await gUM(constraints)).getTracks()) { is(typeof(track.label), "string", "Track label is a string"); is(track.label, device.label, "Track label is the device label"); track.stop(); @@ -77,10 +68,10 @@ runTest(async () => { // Check deviceId failure paths for video. - await mustSucceedWithStream("unknown plain deviceId on video", - () => gUM({ video: { deviceId: unknownId } })); - await mustSucceedWithStream("unknown plain deviceId on audio", - () => gUM({ audio: { deviceId: unknownId } })); + await mustSucceed("unknown plain deviceId on video", + () => gUM({ video: { deviceId: unknownId } })); + await mustSucceed("unknown plain deviceId on audio", + () => gUM({ audio: { deviceId: unknownId } })); await mustFailWith("unknown exact deviceId on video", "OverconstrainedError", "deviceId", () => gUM({ video: { deviceId: { exact: unknownId } } })); @@ -94,8 +85,8 @@ runTest(async () => { const origins = ["https://example.com", "https://test1.example.com"]; info(window.location); - const haveDevicesMap = new Promise(resolve => { - const map = new Map(); + let haveDevicesMap = new Promise(resolve => { + let map = new Map(); window.addEventListener("message", ({origin, data}) => { ok(origins.includes(origin), "Got message from expected origin"); map.set(origin, JSON.parse(data)); @@ -105,9 +96,9 @@ runTest(async () => { }); await Promise.all(origins.map(origin => { - const iframe = document.createElement("iframe"); + let iframe = document.createElement("iframe"); iframe.src = origin + path; - iframe.allow = "camera;microphone;speaker-selection"; + iframe.allow = "camera;microphone"; info(iframe.src); document.documentElement.appendChild(iframe); return new Promise(resolve => iframe.onload = resolve); @@ -115,15 +106,15 @@ runTest(async () => { let devicesMap = await haveDevicesMap; let [sameOriginDevices, differentOriginDevices] = origins.map(o => devicesMap.get(o)); - is(sameOriginDevices.length, devices.length, "same origin same devices"); - is(differentOriginDevices.length, devices.length, "cross origin same devices"); + is(sameOriginDevices.length, devices.length); + is(differentOriginDevices.length, devices.length); [...sameOriginDevices, ...differentOriginDevices].forEach(d => validateDevice(d)); - for (const device of sameOriginDevices) { + for (let device of sameOriginDevices) { ok(devices.find(d => d.deviceId == device.deviceId), "Same origin deviceId for " + device.label + " must match"); } - for (const device of differentOriginDevices) { + for (let device of differentOriginDevices) { ok(!devices.find(d => d.deviceId == device.deviceId), "Different origin deviceId for " + device.label + " must be different"); } diff --git a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_getUserMediaFake.html b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_getUserMediaFake.html index 7952bcba1b93..47c9145770e0 100644 --- a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_getUserMediaFake.html +++ b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_getUserMediaFake.html @@ -9,7 +9,7 @@ "use strict"; createHTML({ - title: "Test labeled devices or speakers aren't exposed in enumerateDevices() after fake getUserMedia()", + title: "Test enumerateDevices() after fake getUserMedia()", bug: "1743524" }); @@ -24,38 +24,47 @@ runTest(async () => { // `fake:true` means that getUserMedia() resolves without any permission // check, and so this should not be sufficient to expose real device info. const stream = await devices.getUserMedia({ audio: true, fake: true }); + // permission.disabled exposes labels - bug 1528042 + const list = await withPrefs( + [["media.navigator.permission.disabled", false]], + async () => devices.enumerateDevices()); stream.getTracks()[0].stop(); - const list = await devices.enumerateDevices(); const labeledDevices = list.filter(({label}) => label != ""); - is(labeledDevices.length, 0, "must be zero labeled devices after fake gUM"); + is(labeledDevices.length, 0, "number of labeled devices after fake gUM"); const outputDevices = list.filter(({kind}) => kind == "audiooutput"); - is(outputDevices.length, 0, "must be zero output devices after fake gUM"); + is(outputDevices.length, 0, "number of output devices after fake gUM"); } { // Check without `fake:true` to verify assumptions about existing devices. - let stream; - try { - stream = await devices.getUserMedia({ audio: true }); - stream.getTracks()[0].stop(); - } catch (e) { - if (e.name == "NotFoundError" && - navigator.userAgent.includes("Mac OS X")) { - todo(false, "Expecting no real audioinput device on Mac test machines"); - return; + const streamPromise = devices.getUserMedia({ audio: true }); + if (navigator.userAgent.includes("Mac OS X")) { + let rejection = "resolved"; + try { + await streamPromise; + } catch (e) { + rejection = e.name; } - throw e; + todo_isnot(rejection, "NotFoundError", + "Expecting no real audioinput device on Mac."); + return; } + const stream = await streamPromise; { const list = await devices.enumerateDevices(); - const audioDevices = list.filter(({kind}) => kind.includes("audio")); - ok(audioDevices.length, "have audio devices after real gUM"); - const unlabeledAudioDevices = audioDevices.filter(({label}) => !label); + // input labels disappear when the track is stopped - bug 1528042 + const unlabeledAudioDevices = + list.filter(({ kind, label }) => { + return kind != "videoinput" && label == "" + }); is(unlabeledAudioDevices.length, 0, - "must be zero unlabeled audio devices after real gUM"); - - const outputDevices = list.filter(({kind}) => kind == "audiooutput"); - isnot(outputDevices.length, 0, "have output devices after real gUM"); + "number of unlabeled audio devices after real gUM"); } + stream.getTracks()[0].stop(); + const list = await devices.enumerateDevices(); + const outputDevices = list.filter(({ kind, label }) => { + return kind == "audiooutput" && label != ""; + }); + isnot(outputDevices.length, 0, "number of output devices after real gUM"); } }); diff --git a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe.html b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe.html index beea3a4f97e9..a893ed3b95be 100644 --- a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe.html +++ b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe.html @@ -7,18 +7,13 @@ Runs inside iframe in test_enumerateDevices.html. */ -const pushPrefs = (...p) => SpecialPowers.pushPrefEnv({set: p}); -const gUM = c => navigator.mediaDevices.getUserMedia(c); +var pushPrefs = (...p) => SpecialPowers.pushPrefEnv({set: p}); +var gUM = c => navigator.mediaDevices.getUserMedia(c); (async () => { await pushPrefs(["media.navigator.streams.fake", true]); - // Validate enumerated devices after gUM. - for (const track of (await gUM({video: true, audio: true})).getTracks()) { - track.stop(); - } - - const devices = await navigator.mediaDevices.enumerateDevices(); + let devices = await navigator.mediaDevices.enumerateDevices(); parent.postMessage(JSON.stringify(devices), "https://example.com:443"); })().catch(e => setTimeout(() => { throw e; })); diff --git a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe_pre_gum.html b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe_pre_gum.html deleted file mode 100644 index f2dc2d1f65bc..000000000000 --- a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_iframe_pre_gum.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -
-
-
- - diff --git a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_legacy.html b/dom/media/webrtc/tests/mochitests/test_enumerateDevices_legacy.html deleted file mode 100644 index c599f2b5994d..000000000000 --- a/dom/media/webrtc/tests/mochitests/test_enumerateDevices_legacy.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - -
-
-
- - diff --git a/dom/media/webrtc/tests/mochitests/test_getUserMedia_basicScreenshare.html b/dom/media/webrtc/tests/mochitests/test_getUserMedia_basicScreenshare.html index cc73de77da23..e10980847dad 100644 --- a/dom/media/webrtc/tests/mochitests/test_getUserMedia_basicScreenshare.html +++ b/dom/media/webrtc/tests/mochitests/test_getUserMedia_basicScreenshare.html @@ -169,9 +169,6 @@ info("Testing screenshare with size and framerate constraints"); SpecialPowers.wrap(document).notifyUserGestureActivation(); - for (const track of stream.getTracks()) { - track.stop(); - } stream = await getUserMedia({ video: { mediaSource: 'screen', @@ -196,8 +193,7 @@ `Height setting ${settings.height} should be correct after gUM (or 0 per bug 1453247)`); colors = ["green", "red", "white", "blue"]; draw(colors); - const streamClone = stream.clone(); - await doVerify(streamClone, colors); + await doVerify(stream.clone(), colors); settings = stream.getTracks()[0].getSettings(); ok(settings.width >= 10 && settings.width <= 100, `Width setting ${settings.width} should be within constraints`); @@ -250,9 +246,6 @@ colors = ["white", "green", "blue", "red"]; draw(colors); await doVerify(stream, colors); - for (const track of [...stream.getTracks(), ...streamClone.getTracks()]) { - track.stop(); - } }); diff --git a/dom/media/webrtc/tests/mochitests/test_getUserMedia_trackCloneCleanup.html b/dom/media/webrtc/tests/mochitests/test_getUserMedia_trackCloneCleanup.html index 60077ec73b75..ae72b54a9639 100644 --- a/dom/media/webrtc/tests/mochitests/test_getUserMedia_trackCloneCleanup.html +++ b/dom/media/webrtc/tests/mochitests/test_getUserMedia_trackCloneCleanup.html @@ -13,10 +13,8 @@ bug: "1294605" }); - runTest(async () => { - await pushPrefs(["media.navigator.permission.fake", true]); - const stream = await getUserMedia({audio: true, video: true, fake: true}); - const clone = stream.clone(); + runTest(() => getUserMedia({audio: true, video: true}).then(stream => { + let clone = stream.clone(); stream.getTracks().forEach(t => t.stop()); stream.clone().getTracks().forEach(t => stream.addTrack(t)); is(stream.getTracks().filter(t => t.readyState == "live").length, 0, @@ -25,7 +23,7 @@ // Bug 1295352: better to be explicit about noGum here wrt future refactoring. return noGum(); - }); + })); diff --git a/dom/media/webrtc/tests/mochitests/test_groupId.html b/dom/media/webrtc/tests/mochitests/test_groupId.html index f2aefe5e80c9..563799c5ac0f 100644 --- a/dom/media/webrtc/tests/mochitests/test_groupId.html +++ b/dom/media/webrtc/tests/mochitests/test_groupId.html @@ -8,15 +8,15 @@ - - - - - - - diff --git a/testing/web-platform/mozilla/tests/mediacapture-streams/permission-helper.js b/testing/web-platform/mozilla/tests/mediacapture-streams/permission-helper.js deleted file mode 100644 index 0a237f7d438f..000000000000 --- a/testing/web-platform/mozilla/tests/mediacapture-streams/permission-helper.js +++ /dev/null @@ -1,24 +0,0 @@ -// Set permissions for camera and microphone using Web Driver -// Status can be one of "granted" or "denied" -// Scope take values from permission names -async function setMediaPermission(status="granted", scope=["camera", "microphone"]) { - try { - for (let s of scope) { - await test_driver.set_permission({ name: s }, status); - } - } catch (e) { - const noSetPermissionSupport = typeof e === "string" && e.match(/set_permission not implemented/); - if (!(noSetPermissionSupport || - (e instanceof Error && e.message.match("unimplemented")) )) { - throw e; - } - // Web Driver not implemented action - // FF: https://bugzilla.mozilla.org/show_bug.cgi?id=1524074 - - // with current WPT runners, will default to granted state for FF and Safari - // throw if status!="granted" to invalidate test results - if (status === "denied") { - assert_implements_optional(!noSetPermissionSupport, "Unable to set permission to denied for this test"); - } - } -} diff --git a/testing/web-platform/tests/audio-output/enumerateDevices-with-selectAudioOutput.https.html b/testing/web-platform/tests/audio-output/enumerateDevices-with-selectAudioOutput.https.html index c1a825592a60..51da44286a76 100644 --- a/testing/web-platform/tests/audio-output/enumerateDevices-with-selectAudioOutput.https.html +++ b/testing/web-platform/tests/audio-output/enumerateDevices-with-selectAudioOutput.https.html @@ -40,9 +40,9 @@ promise_test(async () => { const outputDevices = devices.filter(info => info.kind == "audiooutput"); assert_equals(outputDevices.length, 1, "number of audiooutput devices."); assert_not_equals(selected, undefined); - const [info] = outputDevices; - assert_equals(info.deviceId, selected.deviceId, "deviceId exposed"); - assert_equals(info.groupId, selected.groupId, "groupId exposed"); - assert_equals(info.label, selected.label, "label exposed"); + const info = outputDevices[0]; + assert_equals(info.deviceId, selected.deviceId); + assert_equals(info.groupId, selected.groupId); + assert_equals(info.label, selected.label); }, "enumerateDevices() after selectAudioOutput()"); diff --git a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html index ae09feffa364..58aacf9856ce 100644 --- a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html +++ b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-persistent-permission.https.html @@ -19,7 +19,7 @@ // so enumerateDevices should not list detailed info yet const iframe = document.createElement("iframe"); iframe.setAttribute("allow", "camera 'src';microphone 'src'"); - iframe.src = "/mediacapture-streams/iframe-enumerate-pre-gum.html"; + iframe.src = "/mediacapture-streams/iframe-enumerate.html"; document.body.appendChild(iframe); const loadWatcher = new EventWatcher(t, iframe, ['load']); await loadWatcher.wait_for('load'); diff --git a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html index 6e6dbaf3bba4..2b5687f672b9 100644 --- a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html +++ b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices-returned-objects.https.html @@ -36,8 +36,7 @@ function doTest(callGetUserMedia, testName) assert_equals(device1.deviceId, "", "deviceId is empty before capture"); assert_equals(device1.groupId, "", "groupId is empty before capture"); assert_equals(device1.label, "", "label is empty before capture"); - assert_in_array(device1.kind, ["audioinput", "audiooutput", "videoinput"], - "kind is set to a valid value before capture"); + assert_in_array(device1.kind, ["audioinput", "audiooutput", "videoinput", "kind is set to a valid value before capture"]); } } /* Additionally, at most one device of each kind @@ -53,8 +52,8 @@ function doTest(callGetUserMedia, testName) }, testName); } -doTest(false, "enumerateDevices exposes mostly empty objects ahead of successful getUserMedia call"); -doTest(true, "enumerateDevices exposes expected objects after successful getUserMedia call"); +doTest(false, "enumerateDevices returns expected mostly empty objects in case device-info permission is not granted"); +doTest(true, "enumerateDevices returns expected objects in case device-info permission is granted"); diff --git a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html index 88c07048a1b4..4971f4fc4828 100644 --- a/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html +++ b/testing/web-platform/tests/mediacapture-streams/MediaDevices-enumerateDevices.https.html @@ -23,85 +23,36 @@ promise_test(async () => { assert_not_equals(navigator.mediaDevices.enumerateDevices, undefined, "navigator.mediaDevices.enumerateDevices exists"); - const devices = await navigator.mediaDevices.enumerateDevices(); - for (const {kind, deviceId, label, groupId} of devices) { - assert_in_array(kind, ["videoinput", "audioinput", "audiooutput"]); - assert_equals(deviceId, "", "deviceId should be empty string if getUserMedia was never called successfully."); - assert_equals(label, "", "label should be empty string if getUserMedia was never called successfully."); - assert_equals(groupId, "", "groupId should be empty string if getUserMedia was never called successfully."); - } - assert_less_than_equal(devices.filter(({kind}) => kind == "audioinput").length, - 1, "there should be zero or one audio input device."); - assert_less_than_equal(devices.filter(({kind}) => kind == "videoinput").length, - 1, "there should be zero or one video input device."); - assert_equals(devices.filter(({kind}) => kind == "audiooutput").length, - 0, "there should be no audio output devices."); - assert_less_than_equal(devices.length, 2, - "there should be no more than two devices."); - if (devices.length > 1) { - assert_equals(devices[0].kind, "audioinput", "audioinput is first"); - assert_equals(devices[1].kind, "videoinput", "videoinput is second"); + const deviceList = await navigator.mediaDevices.enumerateDevices(); + for (const mediaInfo of deviceList) { + assert_not_equals(mediaInfo.kind, undefined, "mediaInfo's kind should exist."); + assert_equals(mediaInfo.deviceId, "", "mediaInfo's deviceId should exist and be empty if getUserMedia was never called successfully."); + assert_equals(mediaInfo.label, "", "mediaInfo's label should exist and be empty if getUserMedia was never called successfully."); + assert_equals(mediaInfo.groupId, "", "mediaInfo's groupId should exist and be empty if getUserMedia was never called successfully."); + assert_in_array(mediaInfo.kind, ["videoinput", "audioinput", "audiooutput"]); } + assert_less_than_equal(deviceList.filter((item) => { return item.kind == "audioinput"; }).length, 1, "there should be zero or one audio input device "); + assert_less_than_equal(deviceList.filter((item) => { return item.kind == "videoinput"; }).length, 1, "there should be zero or one video input device "); + }, "mediaDevices.enumerateDevices() is present and working - before capture"); -promise_test(async t => { - await setMediaPermission("granted"); - const stream = await navigator.mediaDevices.getUserMedia({ video: true }); - stream.getTracks()[0].stop(); - - const devices = await navigator.mediaDevices.enumerateDevices(); - const kinds = ["audioinput", "videoinput"]; - for (const {kind, deviceId} of devices) { - assert_in_array(kind, kinds, "camera doesn't expose audiooutput"); - assert_equals(typeof deviceId, "string", "deviceId is a string."); - switch (kind) { - case "videoinput": - assert_greater_than(deviceId.length, 0, "video deviceId should not be empty."); - break; - case "audioinput": - assert_equals(deviceId.length, 0, "audio deviceId should be empty."); - break; - } +promise_test(async () => { + await setMediaPermission("granted", ["microphone"]); + await navigator.mediaDevices.getUserMedia({ audio : true }); + const deviceList = await navigator.mediaDevices.enumerateDevices(); + for (const mediaInfo of deviceList) { + assert_not_equals(mediaInfo.kind, undefined, "mediaInfo's kind should exist."); + assert_not_equals(mediaInfo.deviceId, "", "mediaInfo's deviceId should exist and not be empty."); + assert_in_array(mediaInfo.kind, ["videoinput", "audioinput", "audiooutput"]); } -}, "mediaDevices.enumerateDevices() is working - after video capture"); - -// This test is designed to come after its video counterpart directly above -promise_test(async t => { - const devices1 = await navigator.mediaDevices.enumerateDevices(); - const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - stream.getTracks()[0].stop(); - const devices = await navigator.mediaDevices.enumerateDevices(); - assert_equals(devices.filter(({kind}) => kind == "videoinput").length, - devices1.filter(({kind}) => kind == "videoinput").length, - "same number of (previously exposed) videoinput devices"); - assert_greater_than_equal(devices.filter(d => d.kind == "audioinput").length, - devices1.filter(d => d.kind == "audioinput").length, - "same number or more audioinput devices"); - const order = ["audioinput", "videoinput", "audiooutput"]; - for (const {kind, deviceId} of devices) { - assert_in_array(kind, order, "expected kind"); - assert_equals(typeof deviceId, "string", "deviceId is a string."); - switch (kind) { - case "videoinput": - assert_greater_than(deviceId.length, 0, "video deviceId should not be empty."); - break; - case "audioinput": - assert_greater_than(deviceId.length, 0, "audio deviceId should not be empty."); - break; - } - } - const kinds = devices.map(({kind}) => kind); - const correct = [...kinds].sort((a, b) => order.indexOf(a) - order.indexOf(b)); - assert_equals(JSON.stringify(kinds), JSON.stringify(correct), "correct order"); -}, "mediaDevices.enumerateDevices() is working - after video then audio capture"); +}, "mediaDevices.enumerateDevices() is present and working - after capture"); promise_test(async () => { - const devices = await navigator.mediaDevices.enumerateDevices(); - for (const mediaInfo of devices) { + const deviceList = await navigator.mediaDevices.enumerateDevices(); + for (const mediaInfo of deviceList) { if (mediaInfo.kind == "audioinput" || mediaInfo.kind == "videoinput") { - assert_true("InputDeviceInfo" in window, "InputDeviceInfo exists"); assert_true(mediaInfo instanceof InputDeviceInfo); - } else if (mediaInfo.kind == "audiooutput") { + } else if ( mediaInfo.kind == "audiooutput" ) { assert_true(mediaInfo instanceof MediaDeviceInfo); } else { assert_unreached("mediaInfo.kind should be one of 'audioinput', 'videoinput', or 'audiooutput'.") diff --git a/testing/web-platform/tests/mediacapture-streams/MediaDevices-getUserMedia.https.html b/testing/web-platform/tests/mediacapture-streams/MediaDevices-getUserMedia.https.html index 9376f528974a..96399c804fcf 100644 --- a/testing/web-platform/tests/mediacapture-streams/MediaDevices-getUserMedia.https.html +++ b/testing/web-platform/tests/mediacapture-streams/MediaDevices-getUserMedia.https.html @@ -43,10 +43,6 @@ test(function () { promise_test(async t => { // Both permissions are needed at some point, asking both at once await setMediaPermission(); - // A successful camera gUM call is needed to expose camera information - const afterGum = await navigator.mediaDevices.getUserMedia({video: true}); - afterGum.getTracks()[0].stop(); - assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"], "groupId should be supported"); const devices = await navigator.mediaDevices.enumerateDevices(); @@ -70,10 +66,6 @@ promise_test(async t => { }, 'groupId is correctly supported by getUserMedia() for video devices'); promise_test(async t => { - // A successful microphone gUM call is needed to expose microphone information - const afterGum = await navigator.mediaDevices.getUserMedia({audio: true}); - afterGum.getTracks()[0].stop(); - assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"], "groupId should be supported"); const devices = await navigator.mediaDevices.enumerateDevices(); diff --git a/testing/web-platform/tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html b/testing/web-platform/tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html index 1bda4c748ac5..c1d90a4f4831 100644 --- a/testing/web-platform/tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html +++ b/testing/web-platform/tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html @@ -67,25 +67,18 @@ }, 'A device can be opened twice with different resolutions requested'); promise_test(async t => { - // getUserMedia needs to be called before deviceIds and groupIds are exposed - const afterGum = await navigator.mediaDevices.getUserMedia({ - video: true, audio: true - }); - afterGum.getTracks().forEach(track => track.stop()); - const devices = await navigator.mediaDevices.enumerateDevices(); - const inputDevices = devices.filter(({kind}) => kind != "audiooutput"); - assert_greater_than(inputDevices.length, 1, "have at least 2 test devices"); - for (const {kind, deviceId, groupId} of inputDevices) { - const type = {videoinput: "video", audioinput: "audio"}[kind]; - const stream = await navigator.mediaDevices.getUserMedia({ - [type]: {deviceId: {exact: deviceId}} - }); - const [track] = stream.getTracks(); - const settings = track.getSettings(); - track.stop(); - assert_true(settings.groupId == groupId, "device groupId"); - assert_greater_than(settings.groupId.length, 0, "groupId is not empty"); + const inputDevices = devices.filter(d => d.kind != "audiooutput"); + assert_greater_than(inputDevices.length, 0); + for (const device of inputDevices) { + const device_id_constraint = {deviceId: {exact: device.deviceId}}; + const constraints = device.kind == "audioinput" + ? {audio: device_id_constraint} + : {video: device_id_constraint}; + + const stream = await navigator.mediaDevices.getUserMedia(constraints); + assert_true(stream.getTracks()[0].getSettings().groupId === device.groupId, "device groupId"); + assert_greater_than(device.groupId.length, 0); } }, 'groupId is correctly reported by getSettings() for all input devices'); diff --git a/testing/web-platform/tests/mediacapture-streams/iframe-enumerate-pre-gum.html b/testing/web-platform/tests/mediacapture-streams/iframe-enumerate-pre-gum.html deleted file mode 100644 index a063f8a560d3..000000000000 --- a/testing/web-platform/tests/mediacapture-streams/iframe-enumerate-pre-gum.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/testing/web-platform/tests/mediacapture-streams/message-enumerateddevices-pre-gum.js b/testing/web-platform/tests/mediacapture-streams/message-enumerateddevices-pre-gum.js deleted file mode 100644 index 8628db84a985..000000000000 --- a/testing/web-platform/tests/mediacapture-streams/message-enumerateddevices-pre-gum.js +++ /dev/null @@ -1,4 +0,0 @@ -onmessage = async ({source}) => { - const devices = await navigator.mediaDevices.enumerateDevices(); - source.postMessage({devices: devices.map(d => d.toJSON())}, '*'); -}