Diff
Added: trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping-expected.txt (0 => 240928)
--- trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping-expected.txt 2019-02-04 17:37:01 UTC (rev 240928)
@@ -0,0 +1 @@
+PASS
Added: trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping.html (0 => 240928)
--- trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping.html (rev 0)
+++ trunk/LayoutTests/http/wpt/webrtc/getUserMedia-processSwapping.html 2019-02-04 17:37:01 UTC (rev 240928)
@@ -0,0 +1,41 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>getUserMedia on process swapping</title>
+<body>
+<video id="local"></video>
+<script src=""
+<script>
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+}
+
+async function getUserMediaAndNavigate()
+{
+ local.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
+ await local.play();
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ if (window.testRunner && !testRunner.isDoingMediaCapture) {
+ document.body.innerHTML = "FAIL: no capture state";
+ testRunner.notifyDone();
+ return;
+ }
+ window.location = get_host_info().HTTPS_ORIGIN + "/WebKit/webrtc/getUserMedia-processSwapping.html";
+}
+
+function validateMediaCaptureStateAfterNavigation()
+{
+ if (!window.testRunner) {
+ document.body.innerHTML = "FAIL: Need testRunner API";
+ return;
+ }
+ document.body.innerHTML = testRunner.isDoingMediaCapture ? "FAIL" : "PASS";
+ testRunner.notifyDone();
+}
+
+if (window.location.protocol === "http:")
+ getUserMediaAndNavigate();
+else
+ validateMediaCaptureStateAfterNavigation();
+</script>
+</body>
Modified: trunk/Source/WebKit/ChangeLog (240927 => 240928)
--- trunk/Source/WebKit/ChangeLog 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Source/WebKit/ChangeLog 2019-02-04 17:37:01 UTC (rev 240928)
@@ -1,3 +1,26 @@
+2019-02-04 Youenn Fablet <you...@apple.com>
+
+ Capture state should be managed consistently when doing process swapping
+ https://bugs.webkit.org/show_bug.cgi?id=194122
+ <rdar://problem/47609293>
+
+ Reviewed by Eric Carlson.
+
+ When doing PSON, WebPageProxy::resetState is called.
+ It resets the media state, but does not call the client delegates.
+ Instead of directly updating the media state, call the routine used to update it so that client delegates are called.
+
+ Covered by new API test and layout test.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _mediaCaptureState]):
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::resetState):
+ (WebKit::WebPageProxy::isPlayingMediaDidChange):
+ (WebKit::WebPageProxy::updatePlayingMediaDidChange):
+ * UIProcess/WebPageProxy.h:
+
2019-02-04 Antoine Quint <grao...@apple.com>
Use a dedicated type instead of int32_t for pointer identifiers
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (240927 => 240928)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-02-04 17:37:01 UTC (rev 240928)
@@ -6707,7 +6707,7 @@
editCommand->invalidate();
m_activePopupMenu = nullptr;
- m_mediaState = MediaProducer::IsNotPlaying;
+ updatePlayingMediaDidChange(MediaProducer::IsNotPlaying);
#if ENABLE(POINTER_LOCK)
requestPointerUnlock();
@@ -7762,7 +7762,11 @@
ASSERT(focusManager);
focusManager->updatePlaybackAttributesFromMediaState(this, sourceElementID, newState);
#endif
+ updatePlayingMediaDidChange(newState);
+}
+void WebPageProxy::updatePlayingMediaDidChange(MediaProducer::MediaStateFlags newState)
+{
if (newState == m_mediaState)
return;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (240927 => 240928)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-02-04 17:37:01 UTC (rev 240928)
@@ -1248,6 +1248,7 @@
bool isPlayingAudio() const { return !!(m_mediaState & WebCore::MediaProducer::IsPlayingAudio); }
void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags, uint64_t);
+ void updatePlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags);
bool hasActiveAudioStream() const { return m_mediaState & WebCore::MediaProducer::HasActiveAudioCaptureDevice; }
bool hasActiveVideoStream() const { return m_mediaState & WebCore::MediaProducer::HasActiveVideoCaptureDevice; }
WebCore::MediaProducer::MediaStateFlags mediaStateFlags() const { return m_mediaState; }
Modified: trunk/Tools/ChangeLog (240927 => 240928)
--- trunk/Tools/ChangeLog 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/ChangeLog 2019-02-04 17:37:01 UTC (rev 240928)
@@ -1,3 +1,27 @@
+2019-02-04 Youenn Fablet <you...@apple.com>
+
+ Capture state should be managed consistently when doing process swapping
+ https://bugs.webkit.org/show_bug.cgi?id=194122
+ <rdar://problem/47609293>
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+ (-[GetUserMediaUIDelegate _webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:]):
+ (-[GetUserMediaUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]):
+ (-[GetUserMediaUIDelegate _webView:mediaCaptureStateDidChange:]):
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::isDoingMediaCapture const):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::isDoingMediaCapture const):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+ * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+ (WTR::TestController::isDoingMediaCapture const):
+
2019-02-03 Fujii Hironori <hironori.fu...@sony.com>
[Win] WebKitTestRunners is failing to create the IndexedDB directory.
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (240927 => 240928)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2019-02-04 17:37:01 UTC (rev 240928)
@@ -28,6 +28,7 @@
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
#import <WebKit/WKContentRuleListStore.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKNavigationPrivate.h>
@@ -4719,4 +4720,88 @@
done = false;
}
+static bool isCapturing = false;
+@interface GetUserMediaUIDelegate : NSObject<WKUIDelegate>
+- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler;
+- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler;
+- (void)_webView:(WKWebView *)webView mediaCaptureStateDidChange:(_WKMediaCaptureState)state;
+@end
+
+@implementation GetUserMediaUIDelegate
+- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler
+{
+ decisionHandler(YES);
+}
+
+- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler
+{
+ decisionHandler(@"0x987654321", YES);
+}
+
+- (void)_webView:(WKWebView *)webView mediaCaptureStateDidChange:(_WKMediaCaptureState)state
+{
+ isCapturing = state == _WKMediaCaptureStateActiveCamera;
+}
+@end
+
+static const char* getUserMediaBytes = R"PSONRESOURCE(
+<head>
+<body>
+<script>
+navigator.mediaDevices.getUserMedia({video: true});
+</script>
+</body>
+</head>
+)PSONRESOURCE";
+
+TEST(ProcessSwap, GetUserMediaCaptureState)
+{
+ auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+ processPoolConfiguration.get().processSwapsOnNavigation = YES;
+ processPoolConfiguration.get().prewarmsProcessesAutomatically = YES;
+
+ auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+ auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto preferences = [webViewConfiguration.get() preferences];
+ preferences._mediaCaptureRequiresSecureConnection = NO;
+ preferences._mediaDevicesEnabled = YES;
+ preferences._mockCaptureDevicesEnabled = YES;
+
+ [webViewConfiguration setProcessPool:processPool.get()];
+ auto handler = adoptNS([[PSONScheme alloc] init]);
+ [handler addMappingFromURLString:@"pson://www.webkit.org/getUserMedia.html" toData:getUserMediaBytes];
+ [handler addMappingFromURLString:@"pson://www.apple.org/test.html" toData:""];
+ [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+
+ auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+
+ auto uiDelegate = adoptNS([[GetUserMediaUIDelegate alloc] init]);
+ [webView setUIDelegate: uiDelegate.get()];
+
+ auto request = adoptNS([NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/getUserMedia.html"]]);
+ [webView loadRequest:request.get()];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ TestWebKitAPI::Util::run(&isCapturing);
+
+ auto pid1 = [webView _webProcessIdentifier];
+
+ request = adoptNS([NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.org/test.html"]]);
+ [webView loadRequest:request.get()];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto pid2 = [webView _webProcessIdentifier];
+
+ EXPECT_FALSE(isCapturing);
+ EXPECT_FALSE(pid1 == pid2);
+}
+
#endif // WK_API_ENABLED
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-02-04 17:37:01 UTC (rev 240928)
@@ -217,6 +217,7 @@
void setUserMediaPersistentPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin);
unsigned long userMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
void resetUserMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
+ readonly attribute boolean isDoingMediaCapture;
// Audio testing.
[PassContext] void setAudioResult(object data);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-02-04 17:37:01 UTC (rev 240928)
@@ -1094,6 +1094,15 @@
InjectedBundle::singleton().resetUserMediaPermission();
}
+bool TestRunner::isDoingMediaCapture() const
+{
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsDoingMediaCapture"));
+ WKTypeRef returnData = nullptr;
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), nullptr, &returnData);
+ ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID());
+ return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get());
+}
+
void TestRunner::setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin)
{
WKRetainPtr<WKStringRef> originWK = toWK(origin);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-02-04 17:37:01 UTC (rev 240928)
@@ -319,6 +319,7 @@
void setUserMediaPersistentPermissionForOrigin(bool permission, JSStringRef origin, JSStringRef parentOrigin);
unsigned userMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin) const;
void resetUserMediaPermissionRequestCountForOrigin(JSStringRef origin, JSStringRef parentOrigin);
+ bool isDoingMediaCapture() const;
void setPageVisibility(JSStringRef state);
void resetPageVisibility();
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2019-02-04 17:37:01 UTC (rev 240928)
@@ -2900,6 +2900,12 @@
{
// FIXME: To implement.
}
+
+bool TestController::isDoingMediaCapture() const
+{
+ return false;
+}
+
#endif
struct ResourceStatisticsCallbackContext {
Modified: trunk/Tools/WebKitTestRunner/TestController.h (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/TestController.h 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2019-02-04 17:37:01 UTC (rev 240928)
@@ -287,6 +287,8 @@
void setShouldDismissJavaScriptAlertsAsynchronously(bool);
void handleJavaScriptAlert(WKPageRunJavaScriptAlertResultListenerRef);
+ bool isDoingMediaCapture() const;
+
private:
WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(WKContextConfigurationRef);
WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration(const TestOptions&) const;
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-02-04 17:37:01 UTC (rev 240928)
@@ -1034,6 +1034,10 @@
WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count));
return result;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "IsDoingMediaCapture")) {
+ WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(TestController::singleton().isDoingMediaCapture()));
+ return result;
+ }
if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsDebugMode")) {
ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
Modified: trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm (240927 => 240928)
--- trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm 2019-02-04 16:22:49 UTC (rev 240927)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm 2019-02-04 17:37:01 UTC (rev 240928)
@@ -414,4 +414,13 @@
#endif
}
+bool TestController::isDoingMediaCapture() const
+{
+#if WK_API_ENABLED
+ return m_mainWebView->platformView()._mediaCaptureState != _WKMediaCaptureStateNone;
+#else
+ return false;
+#endif
+}
+
} // namespace WTR