WebKit Bugzilla
Attachment 356379 Details for
Bug 192268
: [MediaStream] 'devicechange' event when more capture device information are revealed.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
bug-192268-20181203073629.patch (text/plain), 18.62 KB, created by
Eric Carlson
on 2018-12-03 07:36:29 PST
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Eric Carlson
Created:
2018-12-03 07:36:29 PST
Size:
18.62 KB
patch
obsolete
>Subversion Revision: 238739 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 0fc0ff66f27d0dee9d5b5db082f80d02c06af282..d6bfffcf5d36d548d057dc6e58eab43022c89559 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,19 @@ >+2018-12-01 Eric Carlson <eric.carlson@apple.com> >+ >+ [MediaStream] 'devicechange' event when more capture device information are revealed. >+ https://bugs.webkit.org/show_bug.cgi?id=192268 >+ >+ Reviewed by Youenn Fablet. >+ >+ Test: fast/mediastream/enumerate-devices-change-event.html >+ >+ * Modules/mediastream/MediaDevicesRequest.cpp: >+ (WebCore::MediaDevicesRequest::start): Remove code to modify device based on access, that is >+ now done in the UI process. >+ (WebCore::MediaDevicesRequest::filterDeviceList): Deleted. >+ * Modules/mediastream/MediaDevicesRequest.h: >+ * platform/mediastream/RealtimeMediaSourceCenter.h: >+ > 2018-11-30 Andy Estes <aestes@apple.com> > > [Cocoa] Add some WKA extension points >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index b74610265c85ba6db48f7625a095e130b43d2191..bc58665bb811be201b1dd824a76fa558fc1c13ae 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,20 @@ >+2018-12-01 Eric Carlson <eric.carlson@apple.com> >+ >+ [MediaStream] 'devicechange' event when more capture device information are revealed. >+ https://bugs.webkit.org/show_bug.cgi?id=192268 >+ >+ Reviewed by Youenn Fablet. >+ >+ * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: >+ (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Call captureDevicesChanged >+ if a filtered device list was returned previously. >+ (WebKit::UserMediaPermissionRequestManagerProxy::resetAccess): Clear m_hasFilteredDeviceList. >+ (WebKit::UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess): New. >+ (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): Filter device >+ list and strip device IDs if gUM permission hasn't been given. >+ (WebKit::UserMediaPermissionRequestManagerProxy::watchdogTimerFired): Clear m_hasFilteredDeviceList. >+ * UIProcess/UserMediaPermissionRequestManagerProxy.h: >+ > 2018-11-30 Andy Estes <aestes@apple.com> > > [Cocoa] Add some WKA extension points >diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp >index dba7a6158e2726d9754feb47a52c662a3e5ebee5..10fdd023747fdad78aafa992f7a1a3284c4563b2 100644 >--- a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp >+++ b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp >@@ -79,28 +79,6 @@ void MediaDevicesRequest::contextDestroyed() > ContextDestructionObserver::contextDestroyed(); > } > >-void MediaDevicesRequest::filterDeviceList(Vector<Ref<MediaDeviceInfo>>& devices) >-{ >-#if PLATFORM(IOS_FAMILY) >- static const int defaultCameraCount = 2; >-#else >- static const int defaultCameraCount = 1; >-#endif >- >- static const int defaultMicrophoneCount = 1; >- >- int cameraCount = 0; >- int microphoneCount = 0; >- devices.removeAllMatching([&](const Ref<MediaDeviceInfo>& device) -> bool { >- if (device->kind() == MediaDeviceInfo::Kind::Videoinput && ++cameraCount > defaultCameraCount) >- return true; >- if (device->kind() == MediaDeviceInfo::Kind::Audioinput && ++microphoneCount > defaultMicrophoneCount) >- return true; >- >- return false; >- }); >-} >- > void MediaDevicesRequest::start() > { > auto& document = downcast<Document>(*scriptExecutionContext()); >@@ -127,7 +105,7 @@ void MediaDevicesRequest::start() > } > > // This lambda keeps |this| alive until the request completes or is canceled. >- auto completion = [this, protectedThis = makeRef(*this), canAccessMicrophone, canAccessCamera] (const Vector<CaptureDevice>& captureDevices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) mutable { >+ auto completion = [this, protectedThis = makeRef(*this), canAccessMicrophone, canAccessCamera] (const Vector<CaptureDevice>& captureDevices, const String& deviceIdentifierHashSalt, bool) mutable { > > m_enumerationRequest = nullptr; > >@@ -138,31 +116,16 @@ void MediaDevicesRequest::start() > document.setDeviceIDHashSalt(deviceIdentifierHashSalt); > > Vector<Ref<MediaDeviceInfo>> devices; >- bool revealIdsAndLabels = originHasPersistentAccess || document.hasHadCaptureMediaStreamTrack(); > for (auto& deviceInfo : captureDevices) { > if (!canAccessMicrophone && deviceInfo.type() == CaptureDevice::DeviceType::Microphone) > continue; > if (!canAccessCamera && deviceInfo.type() == CaptureDevice::DeviceType::Camera) > continue; > >- auto label = emptyString(); >- auto id = emptyString(); >- auto groupId = emptyString(); >- if (revealIdsAndLabels) { >- label = deviceInfo.label(); >- id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(deviceInfo.persistentId(), deviceIdentifierHashSalt); >- if (id.isEmpty()) >- continue; >- groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(deviceInfo.groupId(), deviceIdentifierHashSalt); >- } >- > auto deviceType = deviceInfo.type() == CaptureDevice::DeviceType::Microphone ? MediaDeviceInfo::Kind::Audioinput : MediaDeviceInfo::Kind::Videoinput; >- devices.append(MediaDeviceInfo::create(scriptExecutionContext(), label, id, groupId, deviceType)); >+ devices.append(MediaDeviceInfo::create(scriptExecutionContext(), deviceInfo.label(), deviceInfo.persistentId(), deviceInfo.groupId(), deviceType)); > } > >- if (!revealIdsAndLabels) >- filterDeviceList(devices); >- > callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable { > protectedThis->m_promise.resolve(devices); > }); >diff --git a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h >index 33abbd6759becedd395a8e5cce63c93e282e9482..753e64c543669f1464866ddf0ac11ea9a401d29c 100644 >--- a/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h >+++ b/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h >@@ -51,8 +51,6 @@ private: > > void contextDestroyed() final; > >- void filterDeviceList(Vector<Ref<MediaDeviceInfo>>&); >- > MediaDevices::EnumerateDevicesPromise m_promise; > RefPtr<MediaDevicesRequest> m_protector; > RefPtr<MediaDevicesEnumerationRequest> m_enumerationRequest; >diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h >index 1efffdb6c0b611dec23595bc9294f0f61d0aafc1..93481249849fb98bc93bc085d78fcf84a707d5b1 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h >+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h >@@ -88,7 +88,7 @@ public: > virtual CaptureDeviceManager& videoCaptureDeviceManager() = 0; > virtual CaptureDeviceManager& displayCaptureDeviceManager() = 0; > >- String hashStringWithSalt(const String& id, const String& hashSalt); >+ WEBCORE_EXPORT String hashStringWithSalt(const String& id, const String& hashSalt); > WEBCORE_EXPORT CaptureDevice captureDeviceWithUniqueID(const String& id, const String& hashSalt); > WEBCORE_EXPORT ExceptionOr<void> setDeviceEnabled(const String&, bool); > >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >index 56d3588bf0377b1523895394e65d54a7b73643d4..1a066203e7ce746dd2b0a6cf6fa0acb511b5bef8 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >@@ -164,8 +164,13 @@ void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t > return; > > auto deviceIDHashSalt = m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin()); >- if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) >+ >+ if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) { > m_grantedRequests.append(request.releaseNonNull()); >+ if (m_hasFilteredDeviceList) >+ captureDevicesChanged(); >+ m_hasFilteredDeviceList = false; >+ } > #else > UNUSED_PARAM(userMediaID); > UNUSED_PARAM(audioDevice); >@@ -181,6 +186,7 @@ void UserMediaPermissionRequestManagerProxy::resetAccess(uint64_t frameID) > }); > m_pregrantedRequests.clear(); > m_deniedRequests.clear(); >+ m_hasFilteredDeviceList = false; > } > > const UserMediaPermissionRequestProxy* UserMediaPermissionRequestManagerProxy::searchForGrantedRequest(uint64_t frameID, const SecurityOrigin& userMediaDocumentOrigin, const SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const >@@ -393,12 +399,39 @@ void UserMediaPermissionRequestManagerProxy::getUserMediaPermissionInfo(uint64_t > m_pendingDeviceRequests.take(userMediaID); > request->completionHandler()(userMediaID, false); > } >-} >+} >+ >+bool UserMediaPermissionRequestManagerProxy::wasGrantedVideoOrAudioAccess(uint64_t frameID, const SecurityOrigin& userMediaDocumentOrigin, const SecurityOrigin& topLevelDocumentOrigin) >+{ >+ for (const auto& grantedRequest : m_grantedRequests) { >+ if (grantedRequest->requiresDisplayCapture()) >+ continue; >+ if (!grantedRequest->userMediaDocumentSecurityOrigin().isSameSchemeHostPort(userMediaDocumentOrigin)) >+ continue; >+ if (!grantedRequest->topLevelDocumentSecurityOrigin().isSameSchemeHostPort(topLevelDocumentOrigin)) >+ continue; >+ if (grantedRequest->frameID() != frameID) >+ continue; >+ >+ if (grantedRequest->requiresVideoCapture() || grantedRequest->requiresAudioCapture()) >+ return true; >+ } >+ >+ return false; >+} > #endif > > void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, Ref<SecurityOrigin>&& userMediaDocumentOrigin, Ref<SecurityOrigin>&& topLevelDocumentOrigin) > { > #if ENABLE(MEDIA_STREAM) >+ >+#if PLATFORM(IOS_FAMILY) >+ static const int defaultMaximumCameraCount = 2; >+#else >+ static const int defaultMaximumCameraCount = 1; >+#endif >+ static const int defaultMaximumMicrophoneCount = 1; >+ > auto completionHandler = [this, requestOrigin = userMediaDocumentOrigin.copyRef(), topOrigin = topLevelDocumentOrigin.copyRef()](uint64_t userMediaID, bool originHasPersistentAccess) { > auto pendingRequest = m_pendingDeviceRequests.take(userMediaID); > if (!pendingRequest) >@@ -410,12 +443,39 @@ void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint6 > syncWithWebCorePrefs(); > > auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); >- devices.removeAllMatching([&](auto& device) -> bool { >- return !device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone); >- }); >- >+ auto& request = *pendingRequest; >+ bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(request->frameID(), request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin()); >+ int cameraCount = 0; >+ int microphoneCount = 0; > auto deviceIDHashSalt = m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(requestOrigin.get(), topOrigin.get()); >- m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(devices), WTFMove(deviceIDHashSalt), WTFMove(originHasPersistentAccess)), m_page.pageID()); >+ >+ Vector<CaptureDevice> filteredDevices; >+ for (const auto& device : devices) { >+ if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone)) >+ continue; >+ >+ if (!revealIdsAndLabels) { >+ if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount) >+ continue; >+ if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount) >+ continue; >+ } >+ >+ auto label = emptyString(); >+ auto id = emptyString(); >+ auto groupId = emptyString(); >+ if (revealIdsAndLabels) { >+ label = device.label(); >+ id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt); >+ groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt); >+ } >+ >+ filteredDevices.append(CaptureDevice(id, device.type(), label, groupId)); >+ } >+ >+ m_hasFilteredDeviceList = !revealIdsAndLabels; >+ >+ m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(filteredDevices), WTFMove(deviceIDHashSalt), originHasPersistentAccess), m_page.pageID()); > }; > > getUserMediaPermissionInfo(userMediaID, frameID, WTFMove(completionHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin)); >@@ -484,6 +544,7 @@ void UserMediaPermissionRequestManagerProxy::watchdogTimerFired() > m_grantedRequests.clear(); > m_pregrantedRequests.clear(); > m_currentWatchdogInterval = 0_s; >+ m_hasFilteredDeviceList = false; > } > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >index 847f324452749fc289b16ad74035f26d86df4391..24443db0fb792ab3e8adb7ee59fa3119936a3b7b 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >@@ -83,6 +83,8 @@ private: > Prompt > }; > RequestAction getRequestAction(uint64_t frameID, WebCore::SecurityOrigin& userMediaDocumentOrigin, WebCore::SecurityOrigin& topLevelDocumentOrigin, const WebCore::MediaStreamRequest&, Vector<WebCore::CaptureDevice>& audioDevices, Vector<WebCore::CaptureDevice>& videoDevices); >+ >+ bool wasGrantedVideoOrAudioAccess(uint64_t, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin); > #endif > > void watchdogTimerFired(); >@@ -111,6 +113,7 @@ private: > WebCore::MediaProducer::MediaStateFlags m_captureState { WebCore::MediaProducer::IsNotPlaying }; > RunLoop::Timer<UserMediaPermissionRequestManagerProxy> m_watchdogTimer; > Seconds m_currentWatchdogInterval; >+ bool m_hasFilteredDeviceList { false }; > }; > > } // namespace WebKit >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 99bbb14cfa354474e50980d30b728b20a0dc2b3e..63452c9c72a91d91f2071bc95d55e4a027a3d0b8 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-12-01 Eric Carlson <eric.carlson@apple.com> >+ >+ [MediaStream] 'devicechange' event when more capture device information are revealed. >+ https://bugs.webkit.org/show_bug.cgi?id=192268 >+ >+ Reviewed by Youenn Fablet. >+ >+ * fast/mediastream/device-change-event-2.html: Fix bogus title. >+ * fast/mediastream/enumerate-devices-change-event-expected.txt: Added. >+ * fast/mediastream/enumerate-devices-change-event.html: Added. >+ > 2018-11-30 Zalan Bujtas <zalan@apple.com> > > [LFC][BFC] Compute min/maxHeight margins only when they are needed. >diff --git a/LayoutTests/fast/mediastream/device-change-event-2.html b/LayoutTests/fast/mediastream/device-change-event-2.html >index 614b8d1109dc790299bdbb708becf6ab47939aa5..e780f1156f6670bbeed4056ffbccbea4e84c3cf4 100644 >--- a/LayoutTests/fast/mediastream/device-change-event-2.html >+++ b/LayoutTests/fast/mediastream/device-change-event-2.html >@@ -2,7 +2,7 @@ > <html> > <head> > <meta charset="utf-8"> >- <title>Testing local audio capture playback causes "playing" event to fire</title> >+ <title>Testing 'devicechange' event is fired correctly.</title> > <script src="../../resources/testharness.js"></script> > <script src="../../resources/testharnessreport.js"></script> > <script> >diff --git a/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt b/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7997bd889d62cb8b04c0cf29b654a88f600ebf12 >--- /dev/null >+++ b/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS 'devicechange' event fired after getUserMedia() if enumerateDevices() previously returned filtered list >+ >diff --git a/LayoutTests/fast/mediastream/enumerate-devices-change-event.html b/LayoutTests/fast/mediastream/enumerate-devices-change-event.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ede0dfa46f0dd649aa375d6428765105483aa685 >--- /dev/null >+++ b/LayoutTests/fast/mediastream/enumerate-devices-change-event.html >@@ -0,0 +1,40 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta charset="utf-8"> >+ <script src="../../resources/testharness.js"></script> >+ <script src="../../resources/testharnessreport.js"></script> >+ <script> >+ >+ promise_test(async (test) => { >+ >+ if (window.testRunner) >+ testRunner.setUserMediaPermission(true); >+ >+ let devices1 = await navigator.mediaDevices.enumerateDevices(); >+ >+ let eventCount = 0; >+ await new Promise((resolve, reject) => { >+ navigator.mediaDevices.ondevicechange = (evt) => { >+ ++eventCount; >+ resolve(); >+ } >+ >+ setTimeout(() => { >+ reject("navigator.mediaDevices.ondevicechange took too long") >+ }, 4000); >+ >+ navigator.mediaDevices.getUserMedia({ audio:true, video:true }); >+ }); >+ >+ let devices2 = await navigator.mediaDevices.enumerateDevices(); >+ assert_true(devices1.length < devices2.length, "more devices revealed after gUM"); >+ assert_equals(eventCount, 1, "one event fired"); >+ >+ }, "'devicechange' event fired after getUserMedia() if enumerateDevices() previously returned filtered list"); >+ >+ </script> >+</head> >+<body> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192268
:
356324
| 356379