[MediaStream] Don't reveal device IDs until the user has granted permission to capture
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2018 17:26:49 +0000 (17:26 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2018 17:26:49 +0000 (17:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191112
<rdar://problem/45699932>

Reviewed by Youenn Fablet.

Source/WebCore:

No new tests, existing tests updated.

* Modules/mediastream/MediaDevicesRequest.cpp:
(WebCore::MediaDevicesRequest::start): Don't reveal device ID or group ID until the user
has granted permssion to capture.

LayoutTests:

* TestExpectations: Skip http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
and http/tests/media/media-stream/enumerate-devices-source-id.html for now, they don't make sense
with these changes and will be updated to pass in a future patch.
* fast/mediastream/MediaStreamTrack-getCapabilities.html:
* fast/mediastream/get-user-media-device-id-expected.txt:
* fast/mediastream/get-user-media-device-id.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237643 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
LayoutTests/fast/mediastream/get-user-media-device-id-expected.txt
LayoutTests/fast/mediastream/get-user-media-device-id.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDevicesRequest.cpp

index c3910e9..515221b 100644 (file)
@@ -1,3 +1,18 @@
+2018-10-31  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Don't reveal device IDs until the user has granted permission to capture
+        https://bugs.webkit.org/show_bug.cgi?id=191112
+        <rdar://problem/45699932>
+
+        Reviewed by Youenn Fablet.
+
+        * TestExpectations: Skip http/tests/media/media-stream/enumerate-devices-source-id-persistent.html
+        and http/tests/media/media-stream/enumerate-devices-source-id.html for now, they don't make sense
+        with these changes and will be updated to pass in a future patch.
+        * fast/mediastream/MediaStreamTrack-getCapabilities.html:
+        * fast/mediastream/get-user-media-device-id-expected.txt:
+        * fast/mediastream/get-user-media-device-id.html:
+
 2018-10-31  YUHAN WU  <yuhan_wu@apple.com>
 
         MediaRecorder should fire dataavailable event when all tracks are ended and stop() is called
index 9cd7281..647e909 100644 (file)
@@ -2904,3 +2904,7 @@ webkit.org/b/190032 imported/w3c/web-platform-tests/css/css-scoping/keyframes-00
 fast/mediacapturefromelement/CanvasCaptureMediaStream-imagebitmaprenderingcontext.html [ Skip ]
 fast/mediacapturefromelement/CanvasCaptureMediaStream-framerate-0.html [ Skip ]
 fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html [ Skip ]
+
+# FIXME: The behavior of navigator.mediaDevices.enumerateDevices is in flux, skip these tests for now.
+http/tests/media/media-stream/enumerate-devices-source-id-persistent.html [ Skip ]
+http/tests/media/media-stream/enumerate-devices-source-id.html [ Skip ]
index 017c60c..76bcd26 100644 (file)
@@ -2,11 +2,13 @@
 <html>
     <head>
         <script src="../../resources/js-test-pre.js"></script>
-        <script src="./resources/getUserMedia-helper.js"></script>
         <script>
             var mediaStream;
             var devices;
 
+            if (window.testRunner)
+                testRunner.setUserMediaPermission(true);
+
             function limitPrecision(value, precision)
             {
                 if (typeof value === "string")
                 finishJSTest();
             }
 
-            function start()
+            async function start()
             {
                 description("Tests MediaStreamTrack.getCapabilities.");
-                navigator.mediaDevices.enumerateDevices().then(deviceInfoArray => {
-                    devices = deviceInfoArray;
-                    getUserMedia("allow", {audio:true, video:true}, gotStream);
-                }, e => {
-                    testFailed('enumerateDevices failed:' + e);
-                    finishJSTest();
-                });
+
+                mediaStream = await navigator.mediaDevices.getUserMedia({ audio:true, video:true });
+                devices = await navigator.mediaDevices.enumerateDevices();
+
+                listTrackProperties(mediaStream.getVideoTracks()[0]);
+                listTrackProperties(mediaStream.getAudioTracks()[0]);
+                finishJSTest();
             }
 
             window.jsTestIsAsync = true;
index d187b54..098a812 100644 (file)
@@ -1,4 +1,5 @@
 
+PASS Device IDs should be empty initially 
 PASS Collect device IDs 
 PASS Pass device IDs as exact constraints 
 PASS Pass device IDs as optional constraints 
index af54386..cc6f0ee 100644 (file)
         return navigator.mediaDevices.enumerateDevices()
             .then((devices) => {
                 devices.forEach((device) => {
+                    assert_true(device.deviceId.length == 0 , "device.deviceId is empty before permission to capture");
+                });
+            });
+    }, "Device IDs should be empty initially");
+    
+    promise_test((test) => {
+        return navigator.mediaDevices.getUserMedia({ audio:true, video:true })
+            .then((stream) => {
+                return navigator.mediaDevices.enumerateDevices();
+            }).then(devices => {
+                devices.forEach((device) => {
                     let kind = device.kind == "audioinput" ? "audio" : "video";
                     deviceIds.push({ type: kind, id : device.deviceId});
                 });
             });
     }, "Collect device IDs");
-    
+
     let constraints = { };
 
     promise_test((test) => {
index 92912b2..72f396c 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-31  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] Don't reveal device IDs until the user has granted permission to capture
+        https://bugs.webkit.org/show_bug.cgi?id=191112
+        <rdar://problem/45699932>
+
+        Reviewed by Youenn Fablet.
+
+        No new tests, existing tests updated.
+
+        * Modules/mediastream/MediaDevicesRequest.cpp:
+        (WebCore::MediaDevicesRequest::start): Don't reveal device ID or group ID until the user 
+        has granted permssion to capture.
+
 2018-10-31  YUHAN WU  <yuhan_wu@apple.com>
 
         MediaRecorder should fire dataavailable event when all tracks are ended and stop() is called
index 25d565e..203d240 100644 (file)
@@ -115,21 +115,24 @@ void MediaDevicesRequest::start()
         document.setDeviceIDHashSalt(deviceIdentifierHashSalt);
 
         Vector<Ref<MediaDeviceInfo>> devices;
+        bool revealIdsAndLabels = originHasPersistentAccess || document.hasHadCaptureMediaStreamTrack();
         for (auto& deviceInfo : captureDevices) {
             auto label = emptyString();
-            if (originHasPersistentAccess || document.hasHadCaptureMediaStreamTrack())
+            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 id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(deviceInfo.persistentId(), deviceIdentifierHashSalt);
-            if (id.isEmpty())
-                continue;
-
-            auto 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));
         }
 
-        if (!originHasPersistentAccess && !document.hasHadCaptureMediaStreamTrack())
+        if (!revealIdsAndLabels)
             filterDeviceList(devices);
 
         callOnMainThread([protectedThis = makeRef(*this), devices = WTFMove(devices)]() mutable {