Diff
Modified: trunk/LayoutTests/ChangeLog (238795 => 238796)
--- trunk/LayoutTests/ChangeLog 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/LayoutTests/ChangeLog 2018-12-03 16:28:31 UTC (rev 238796)
@@ -1,3 +1,14 @@
+2018-12-03 Eric Carlson <[email protected]>
+
+ [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-12-03 Guillaume Emont <[email protected]>
Gardening: unskip marsaglia.js on arm
Modified: trunk/LayoutTests/fast/mediastream/device-change-event-2.html (238795 => 238796)
--- trunk/LayoutTests/fast/mediastream/device-change-event-2.html 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/LayoutTests/fast/mediastream/device-change-event-2.html 2018-12-03 16:28:31 UTC (rev 238796)
@@ -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=""
<script src=""
<script>
Added: trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt (0 => 238796)
--- trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event-expected.txt 2018-12-03 16:28:31 UTC (rev 238796)
@@ -0,0 +1,3 @@
+
+PASS 'devicechange' event fired after getUserMedia() if enumerateDevices() previously returned filtered list
+
Added: trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event.html (0 => 238796)
--- trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/enumerate-devices-change-event.html 2018-12-03 16:28:31 UTC (rev 238796)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src=""
+ <script src=""
+ <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>
Modified: trunk/Source/WebCore/ChangeLog (238795 => 238796)
--- trunk/Source/WebCore/ChangeLog 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebCore/ChangeLog 2018-12-03 16:28:31 UTC (rev 238796)
@@ -1,3 +1,19 @@
+2018-12-03 Eric Carlson <[email protected]>
+
+ [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-12-03 Wenson Hsieh <[email protected]>
[iOSMac] Unable to upload non-image files using drag and drop in WKWebView
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp (238795 => 238796)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp 2018-12-03 16:28:31 UTC (rev 238796)
@@ -79,28 +79,6 @@
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 @@
}
// 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,7 +116,6 @@
document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
Vector<Ref<MediaDeviceInfo>> devices;
- bool revealIdsAndLabels = originHasPersistentAccess || document.hasHadCaptureMediaStreamTrack();
for (auto& deviceInfo : captureDevices) {
if (!canAccessMicrophone && deviceInfo.type() == CaptureDevice::DeviceType::Microphone)
continue;
@@ -145,24 +122,10 @@
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);
});
Modified: trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h (238795 => 238796)
--- trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebCore/Modules/mediastream/MediaDevicesRequest.h 2018-12-03 16:28:31 UTC (rev 238796)
@@ -51,8 +51,6 @@
void contextDestroyed() final;
- void filterDeviceList(Vector<Ref<MediaDeviceInfo>>&);
-
MediaDevices::EnumerateDevicesPromise m_promise;
RefPtr<MediaDevicesRequest> m_protector;
RefPtr<MediaDevicesEnumerationRequest> m_enumerationRequest;
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (238795 => 238796)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h 2018-12-03 16:28:31 UTC (rev 238796)
@@ -88,7 +88,7 @@
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);
Modified: trunk/Source/WebKit/ChangeLog (238795 => 238796)
--- trunk/Source/WebKit/ChangeLog 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebKit/ChangeLog 2018-12-03 16:28:31 UTC (rev 238796)
@@ -1,3 +1,20 @@
+2018-12-03 Eric Carlson <[email protected]>
+
+ [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-12-03 Keith Rollin <[email protected]>
Remove Network Capture
Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (238795 => 238796)
--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp 2018-12-03 16:28:31 UTC (rev 238796)
@@ -164,8 +164,13 @@
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 @@
});
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 @@
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 @@
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());
- 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 @@
m_grantedRequests.clear();
m_pregrantedRequests.clear();
m_currentWatchdogInterval = 0_s;
+ m_hasFilteredDeviceList = false;
}
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (238795 => 238796)
--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h 2018-12-03 15:42:12 UTC (rev 238795)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h 2018-12-03 16:28:31 UTC (rev 238796)
@@ -83,6 +83,8 @@
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 @@
WebCore::MediaProducer::MediaStateFlags m_captureState { WebCore::MediaProducer::IsNotPlaying };
RunLoop::Timer<UserMediaPermissionRequestManagerProxy> m_watchdogTimer;
Seconds m_currentWatchdogInterval;
+ bool m_hasFilteredDeviceList { false };
};
} // namespace WebKit