[Cocoa] Run camera capture in UIProcess by default in layout tests
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Dec 2019 11:11:44 +0000 (11:11 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Dec 2019 11:11:44 +0000 (11:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204512

Reviewed by Eric Carlson.

Source/WebCore:

Remove no longer useful internals API once we are moving capture to UIProcess.

* platform/mediastream/RealtimeMediaSourceFactory.h:
* testing/Internals.cpp:
(WebCore::Internals::Internals):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

* UIProcess/UserMediaProcessManager.cpp:
(WebKit::UserMediaProcessManager::willCreateMediaStream):
Do not send sandbox extensions in case capture happens in UIProcess.
* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::Source::~Source):
(WebKit::UserMediaCaptureManager::createCaptureSource):
Register/unregister sources as active/unactive sources to the factory.

Tools:

By defaut, enable capture in UIProcess on Cocoa side.

* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetPreferencesToConsistentValues):
(WTR::updateTestOptionsFromTestHeader):
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::hasSameInitializationOptions const):

LayoutTests:

Update tests to remove use of the removed internals API and disable
camera capture in UIProcess for two tests that exihibit shortcomings of our current UIProcess camera capture support.

* fast/mediastream/constraint-intrinsic-size.html:
* fast/mediastream/media-stream-page-muted.html:
* fast/mediastream/mediastreamtrack-video-clone.html:
* fast/mediastream/mock-media-source-expected.txt:
* fast/mediastream/mock-media-source.html:
* fast/mediastream/overconstrainederror-constraint.html:
* webrtc/video-rotation.html:

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/constraint-intrinsic-size.html
LayoutTests/fast/mediastream/media-stream-page-muted.html
LayoutTests/fast/mediastream/mediastreamtrack-video-clone.html
LayoutTests/fast/mediastream/mock-media-source-expected.txt
LayoutTests/fast/mediastream/mock-media-source.html
LayoutTests/fast/mediastream/overconstrainederror-constraint.html
LayoutTests/webrtc/video-rotation.html
Source/WebCore/ChangeLog
Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/UserMediaProcessManager.cpp
Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp
Tools/ChangeLog
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestOptions.h

index 877d7e1..a4fd70f 100644 (file)
@@ -1,3 +1,21 @@
+2019-12-03  youenn fablet  <youenn@apple.com>
+
+        [Cocoa] Run camera capture in UIProcess by default in layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=204512
+
+        Reviewed by Eric Carlson.
+
+        Update tests to remove use of the removed internals API and disable
+        camera capture in UIProcess for two tests that exihibit shortcomings of our current UIProcess camera capture support.
+
+        * fast/mediastream/constraint-intrinsic-size.html:
+        * fast/mediastream/media-stream-page-muted.html:
+        * fast/mediastream/mediastreamtrack-video-clone.html:
+        * fast/mediastream/mock-media-source-expected.txt:
+        * fast/mediastream/mock-media-source.html:
+        * fast/mediastream/overconstrainederror-constraint.html:
+        * webrtc/video-rotation.html:
+
 2019-12-03  Antti Koivisto  <antti@apple.com>
 
         [LFC][Integration] Setup root box properties
index 161d64c..566cb11 100644 (file)
@@ -9,12 +9,8 @@
     <body>
 
         <script>
-            if (window.testRunner)
-                testRunner.setUserMediaPermission(true);
-            if (window.internals) {
-                window.internals.setMockMediaCaptureDevicesEnabled(true);
+            if (window.internals)
                 window.internals.settings.setScreenCaptureEnabled(true);
-            }
 
             function callGetDisplayMedia(options)
             {
index 8b1438b..6d219b7 100644 (file)
         }
 
         jsTestIsAsync = true;
-        if (window.testRunner) {
-            testRunner.setUserMediaPermission(true);
+        if (window.testRunner)
             testRunner.waitUntilDone();
-        }
-        if (window.internals) {
-            window.internals.setMockMediaCaptureDevicesEnabled(true);
+        if (window.internals)
             window.internals.settings.setScreenCaptureEnabled(true);
-        }
 
         (async function() {
             try {
index ca43910..0e17b41 100644 (file)
@@ -1,4 +1,4 @@
-Test enabling/disabling mock media capture devices
+Test mock media capture devices
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
@@ -7,15 +7,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 *** Mock capture devices should be enabled by default
 PASS mediaStream is an instance of Object
 PASS mediaStream.getTracks().length is 2
-
-*** Disable mock capture devices
-internals.setMockMediaCaptureDevicesEnabled(false)
-PASS mediaDevices.getUserMedia() failed with NotReadableError
-
-*** Enable mock capture devices
-internals.setMockMediaCaptureDevicesEnabled(true)
-PASS mediaStream is an instance of Object
-PASS mediaStream.getTracks().length is 2
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c56faf0..7dac252 100644 (file)
@@ -5,27 +5,6 @@
         <script>
             var mediaStream;
 
-            function testWhenDisabled()
-            {
-                debug(`<br>*** Disable mock capture devices`);
-                if (window.internals)
-                    evalAndLog(`internals.setMockMediaCaptureDevicesEnabled(false)`);
-                navigator.mediaDevices
-                    .getUserMedia({audio:{}, video:{}})
-                    .then(function(stream) {
-                        mediaStream = stream;
-                        testFailed(`mediaDevices.getUserMedia() succeeded when no devices should be available`);
-                        finishJSTest();
-                    })
-                    .catch(function(err) {
-                        testPassed(`mediaDevices.getUserMedia() failed with ${err.name}`);
-                        debug(`<br>*** Enable mock capture devices`);
-                        if (window.internals)
-                            evalAndLog(`internals.setMockMediaCaptureDevicesEnabled(true)`);
-                        testWhenEnabled(null);
-                    });
-            }
-
             function testWhenEnabled(nextTest)
             {
                 navigator.mediaDevices
             function start()
             {
                 debug(`<br>*** Mock capture devices should be enabled by default`);
-                if (window.testRunner)
-                    testRunner.setUserMediaPermission(true);
-
-                testWhenEnabled(testWhenDisabled);
+                testWhenEnabled();
             }
 
         </script>
@@ -62,7 +38,7 @@
         <p id="description"></p>
         <div id="console"></div>
         <script>
-            description("Test enabling/disabling mock media capture devices");
+            description("Test mock media capture devices");
             window.jsTestIsAsync = true;
 
             window.successfullyParsed = true;
index e8396a0..ce3558b 100644 (file)
@@ -11,8 +11,6 @@
         <script>
 if (window.testRunner)
     testRunner.setUserMediaPermission(true);
-if (window.internals)
-    window.internals.setMockMediaCaptureDevicesEnabled(true);
 
 promise_test(async () => {
     return navigator.mediaDevices.getUserMedia({audio: {deviceId: {exact:"none"}}}).then(
index 584056c..bab9346 100644 (file)
@@ -1,3 +1,4 @@
+<!-- webkit-test-runner [ enableCaptureVideoInUIProcess=false ] -->
 <!doctype html>
 <html>
     <head>
index 23be486..08d8193 100644 (file)
@@ -1,3 +1,18 @@
+2019-12-03  youenn fablet  <youenn@apple.com>
+
+        [Cocoa] Run camera capture in UIProcess by default in layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=204512
+
+        Reviewed by Eric Carlson.
+
+        Remove no longer useful internals API once we are moving capture to UIProcess.
+
+        * platform/mediastream/RealtimeMediaSourceFactory.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::Internals):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-12-03  Antti Koivisto  <antti@apple.com>
 
         [LFC][Integration] Setup root box properties
index a3d52f0..32f9d34 100644 (file)
@@ -40,8 +40,8 @@ struct MediaConstraints;
 
 class SingleSourceFactory {
 public:
-    void setActiveSource(RealtimeMediaSource&);
-    void unsetActiveSource(RealtimeMediaSource&);
+    WEBCORE_EXPORT void setActiveSource(RealtimeMediaSource&);
+    WEBCORE_EXPORT void unsetActiveSource(RealtimeMediaSource&);
     RealtimeMediaSource* activeSource() { return m_activeSource; }
 
 private:
index 87f73ad..5285bde 100644 (file)
@@ -553,7 +553,6 @@ Internals::Internals(Document& document)
 #endif
 
 #if ENABLE(MEDIA_STREAM)
-    setMockMediaCaptureDevicesEnabled(true);
     setMediaCaptureRequiresSecureConnection(false);
 #endif
 
@@ -1547,13 +1546,6 @@ void Internals::setShouldInterruptAudioOnPageVisibilityChange(bool shouldInterru
     RuntimeEnabledFeatures::sharedFeatures().setInterruptAudioOnPageVisibilityChangeEnabled(shouldInterrupt);
 }
 
-void Internals::setMockMediaCaptureDevicesEnabled(bool enabled)
-{
-    Document* document = contextDocument();
-    if (auto* page = document->page())
-        page->settings().setMockCaptureDevicesEnabled(enabled);
-}
-
 void Internals::setMediaCaptureRequiresSecureConnection(bool enabled)
 {
     Document* document = contextDocument();
index 443f134..a9b1b7d 100644 (file)
@@ -542,7 +542,6 @@ public:
 
 #if ENABLE(MEDIA_STREAM)
     void setShouldInterruptAudioOnPageVisibilityChange(bool);
-    void setMockMediaCaptureDevicesEnabled(bool);
     void setMediaCaptureRequiresSecureConnection(bool);
     void setCustomPrivateRecorderCreator();
 #endif
index a5e4233..5492170 100644 (file)
@@ -620,7 +620,6 @@ enum CompositingPolicy {
     [Conditional=WIRELESS_PLAYBACK_TARGET] void setMockMediaPlaybackTargetPickerEnabled(boolean enabled);
     [Conditional=WIRELESS_PLAYBACK_TARGET, MayThrowException] void setMockMediaPlaybackTargetPickerState(DOMString deviceName, DOMString deviceState);
     [Conditional=WIRELESS_PLAYBACK_TARGET] void mockMediaPlaybackTargetPickerDismissPopup();
-    [Conditional=MEDIA_STREAM] void setMockMediaCaptureDevicesEnabled(boolean enabled);
     [Conditional=MEDIA_STREAM] void setCustomPrivateRecorderCreator();
 
     [Conditional=WEB_AUDIO] void useMockAudioDestinationCocoa();
index 993c16a..cc28a40 100644 (file)
@@ -1,3 +1,18 @@
+2019-12-03  youenn fablet  <youenn@apple.com>
+
+        [Cocoa] Run camera capture in UIProcess by default in layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=204512
+
+        Reviewed by Eric Carlson.
+
+        * UIProcess/UserMediaProcessManager.cpp:
+        (WebKit::UserMediaProcessManager::willCreateMediaStream):
+        Do not send sandbox extensions in case capture happens in UIProcess.
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::Source::~Source):
+        (WebKit::UserMediaCaptureManager::createCaptureSource):
+        Register/unregister sources as active/unactive sources to the factory.
+
 2019-12-03  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         WebDriver: handle elements of type file in send keys command
index 3de7e7d..250f64a 100644 (file)
@@ -75,15 +75,13 @@ bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa
     auto& process = proxy.page().process();
     size_t extensionCount = 0;
 
-    if (withAudio && !process.hasAudioCaptureExtension())
+    bool needsAudioSandboxExtension = withAudio && !process.hasAudioCaptureExtension() && !proxy.page().preferences().captureAudioInUIProcessEnabled();
+    if (needsAudioSandboxExtension)
         extensionCount++;
-    else
-        withAudio = false;
 
-    if (withVideo && !process.hasVideoCaptureExtension())
+    bool needsVideoSandboxExtension = withVideo && !process.hasVideoCaptureExtension() && !proxy.page().preferences().captureVideoInUIProcessEnabled();
+    if (needsVideoSandboxExtension)
         extensionCount++;
-    else
-        withVideo = false;
 
     if (extensionCount) {
         SandboxExtension::HandleArray handles;
@@ -93,11 +91,11 @@ bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa
             handles.allocate(extensionCount);
             ids.reserveInitialCapacity(extensionCount);
 
-            if (withAudio && SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount]))
-                ids.append(audioExtensionPath);
+            if (needsAudioSandboxExtension && SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount]))
+                ids.uncheckedAppend(audioExtensionPath);
 
-            if (withVideo && SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount]))
-                ids.append(videoExtensionPath);
+            if (needsVideoSandboxExtension && SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount]))
+                ids.uncheckedAppend(videoExtensionPath);
 
             if (ids.size() != handles.size()) {
                 WTFLogAlways("Could not create a required sandbox extension, capture will fail!");
@@ -108,9 +106,9 @@ bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa
         for (const auto& id : ids)
             RELEASE_LOG(WebRTC, "UserMediaProcessManager::willCreateMediaStream - granting extension %s", id.utf8().data());
 
-        if (withAudio)
+        if (needsAudioSandboxExtension)
             process.grantAudioCaptureExtension();
-        if (withVideo)
+        if (needsVideoSandboxExtension)
             process.grantVideoCaptureExtension();
         process.send(Messages::WebProcess::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), 0);
     }
index 6fd743e..2585557 100644 (file)
@@ -71,6 +71,11 @@ public:
     {
         if (type() == Type::Audio)
             storage().invalidate();
+        else if (type() == Type::Video) {
+#if PLATFORM(IOS_FAMILY)
+            RealtimeMediaSourceCenter::singleton().videoCaptureFactory().unsetActiveSource(*this);
+#endif
+        }
     }
 
     SharedRingBufferStorage& storage()
@@ -257,6 +262,12 @@ WebCore::CaptureSourceOrError UserMediaCaptureManager::createCaptureSource(const
     auto source = adoptRef(*new Source(String::number(id), type, device.type(), String { settings.label().string() }, WTFMove(hashSalt), id, *this));
     source->setSettings(WTFMove(settings));
     m_sources.add(id, source.copyRef());
+
+#if PLATFORM(IOS_FAMILY)
+    if (type == WebCore::RealtimeMediaSource::Type::Video)
+        RealtimeMediaSourceCenter::singleton().videoCaptureFactory().setActiveSource(source);
+#endif
+
     return WebCore::CaptureSourceOrError(WTFMove(source));
 }
 
index 35e92f5..d8ae661 100644 (file)
@@ -1,3 +1,18 @@
+2019-12-03  youenn fablet  <youenn@apple.com>
+
+        [Cocoa] Run camera capture in UIProcess by default in layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=204512
+
+        Reviewed by Eric Carlson.
+
+        By defaut, enable capture in UIProcess on Cocoa side.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::resetPreferencesToConsistentValues):
+        (WTR::updateTestOptionsFromTestHeader):
+        * WebKitTestRunner/TestOptions.h:
+        (WTR::TestOptions::hasSameInitializationOptions const):
+
 2019-12-03  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Unreviewed. Focus the location bar on CTRL+l in GTK MiniBrowser
index 14db2d2..beb543b 100644 (file)
@@ -815,6 +815,9 @@ void TestController::resetPreferencesToConsistentValues(const TestOptions& optio
     for (const auto& internalDebugFeature : options.internalDebugFeatures)
         WKPreferencesSetInternalDebugFeatureForKey(preferences, internalDebugFeature.value, toWK(internalDebugFeature.key).get());
 
+#if PLATFORM(COCOA)
+    WKPreferencesSetCaptureVideoInUIProcessEnabled(preferences, options.enableCaptureVideoInUIProcess);
+#endif
     WKPreferencesSetProcessSwapOnNavigationEnabled(preferences, options.contextOptions.shouldEnableProcessSwapOnNavigation());
     WKPreferencesSetPageVisibilityBasedProcessSuppressionEnabled(preferences, options.enableAppNap);
     WKPreferencesSetOfflineWebApplicationCacheEnabled(preferences, true);
@@ -1446,6 +1449,8 @@ static void updateTestOptionsFromTestHeader(TestOptions& testOptions, const std:
             testOptions.enableLazyImageLoading = parseBooleanTestHeaderValue(value);
         else if (key == "allowsLinkPreview")
             testOptions.allowsLinkPreview = parseBooleanTestHeaderValue(value);
+        else if (key == "enableCaptureVideoInUIProcess")
+            testOptions.enableCaptureVideoInUIProcess = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
     }
 }
index 515d5bf..a5ec252 100644 (file)
@@ -97,6 +97,7 @@ struct TestOptions {
     bool enableBackForwardCache { false };
     bool enableLazyImageLoading { false };
     bool allowsLinkPreview { true };
+    bool enableCaptureVideoInUIProcess { true };
 
     double contentInsetTop { 0 };
 
@@ -156,7 +157,8 @@ struct TestOptions {
             || enableAppNap != options.enableAppNap
             || enableBackForwardCache != options.enableBackForwardCache
             || enableLazyImageLoading != options.enableLazyImageLoading
-            || allowsLinkPreview != options.allowsLinkPreview)
+            || allowsLinkPreview != options.allowsLinkPreview
+            || enableCaptureVideoInUIProcess != options.enableCaptureVideoInUIProcess)
             return false;
 
         if (!contextOptions.hasSameInitializationOptions(options.contextOptions))