- Revision
- 276504
- Author
- [email protected]
- Date
- 2021-04-23 10:21:25 -0700 (Fri, 23 Apr 2021)
Log Message
Fix KVO for camera/microphone capture state WKWebView API
https://bugs.webkit.org/show_bug.cgi?id=224922
<rdar://problem/77008199>
Reviewed by Eric Carlson.
Source/WebKit:
Add missing willChange observer call and migrate keys to API keys.
Covered by API test.
* UIProcess/Cocoa/PageClientImplCocoa.h:
* UIProcess/Cocoa/PageClientImplCocoa.mm:
(WebKit::PageClientImplCocoa::microphoneCaptureWillChange):
(WebKit::PageClientImplCocoa::cameraCaptureWillChange):
(WebKit::PageClientImplCocoa::microphoneCaptureChanged):
(WebKit::PageClientImplCocoa::cameraCaptureChanged):
* UIProcess/PageClient.h:
(WebKit::PageClient::microphoneCaptureWillChange):
(WebKit::PageClient::cameraCaptureWillChange):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::updateReportedMediaCaptureState):
Tools:
Add tests for capture state API.
* TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
(-[MediaCaptureObserver observeValueForKeyPath:ofObject:change:context:]):
(TestWebKitAPI::waitUntilCameraState):
(TestWebKitAPI::waitUntilMicrophoneState):
(TestWebKitAPI::TEST):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (276503 => 276504)
--- trunk/Source/WebKit/ChangeLog 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Source/WebKit/ChangeLog 2021-04-23 17:21:25 UTC (rev 276504)
@@ -1,3 +1,26 @@
+2021-04-23 Youenn Fablet <[email protected]>
+
+ Fix KVO for camera/microphone capture state WKWebView API
+ https://bugs.webkit.org/show_bug.cgi?id=224922
+ <rdar://problem/77008199>
+
+ Reviewed by Eric Carlson.
+
+ Add missing willChange observer call and migrate keys to API keys.
+ Covered by API test.
+
+ * UIProcess/Cocoa/PageClientImplCocoa.h:
+ * UIProcess/Cocoa/PageClientImplCocoa.mm:
+ (WebKit::PageClientImplCocoa::microphoneCaptureWillChange):
+ (WebKit::PageClientImplCocoa::cameraCaptureWillChange):
+ (WebKit::PageClientImplCocoa::microphoneCaptureChanged):
+ (WebKit::PageClientImplCocoa::cameraCaptureChanged):
+ * UIProcess/PageClient.h:
+ (WebKit::PageClient::microphoneCaptureWillChange):
+ (WebKit::PageClient::cameraCaptureWillChange):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::updateReportedMediaCaptureState):
+
2021-04-23 Chris Dumez <[email protected]>
Improve our constructDeletedValue() template specializations
Modified: trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h (276503 => 276504)
--- trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h 2021-04-23 17:21:25 UTC (rev 276504)
@@ -77,6 +77,8 @@
void storeAppHighlight(const WebCore::AppHighlight&) final;
#endif
+ void microphoneCaptureWillChange() final;
+ void cameraCaptureWillChange() final;
void microphoneCaptureChanged() final;
void cameraCaptureChanged() final;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm (276503 => 276504)
--- trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm 2021-04-23 17:21:25 UTC (rev 276504)
@@ -147,14 +147,24 @@
return m_alternativeTextUIController->alternativesForContext(dictationContext);
}
+void PageClientImplCocoa::microphoneCaptureWillChange()
+{
+ [m_webView willChangeValueForKey:@"microphoneCaptureState"];
+}
+
+void PageClientImplCocoa::cameraCaptureWillChange()
+{
+ [m_webView willChangeValueForKey:@"cameraCaptureState"];
+}
+
void PageClientImplCocoa::microphoneCaptureChanged()
{
- [m_webView didChangeValueForKey:@"_microphoneCaptureState"];
+ [m_webView didChangeValueForKey:@"microphoneCaptureState"];
}
void PageClientImplCocoa::cameraCaptureChanged()
{
- [m_webView didChangeValueForKey:@"_cameraCaptureState"];
+ [m_webView didChangeValueForKey:@"cameraCaptureState"];
}
}
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (276503 => 276504)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2021-04-23 17:21:25 UTC (rev 276504)
@@ -542,6 +542,8 @@
virtual void didHandleAcceptedCandidate() = 0;
#endif
+ virtual void microphoneCaptureWillChange() { }
+ virtual void cameraCaptureWillChange() { }
virtual void microphoneCaptureChanged() { }
virtual void cameraCaptureChanged() { }
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (276503 => 276504)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-04-23 17:21:25 UTC (rev 276504)
@@ -9230,8 +9230,14 @@
bool microphoneCaptureChanged = (m_reportedMediaCaptureState & MediaProducer::AudioCaptureMask) != (activeCaptureState & MediaProducer::AudioCaptureMask);
bool cameraCaptureChanged = (m_reportedMediaCaptureState & MediaProducer::VideoCaptureMask) != (activeCaptureState & MediaProducer::VideoCaptureMask);
+ if (microphoneCaptureChanged)
+ pageClient().microphoneCaptureWillChange();
+ if (cameraCaptureChanged)
+ pageClient().cameraCaptureWillChange();
+
m_reportedMediaCaptureState = activeCaptureState;
m_uiClient->mediaCaptureStateDidChange(m_mediaState);
+
if (microphoneCaptureChanged)
pageClient().microphoneCaptureChanged();
if (cameraCaptureChanged)
Modified: trunk/Tools/ChangeLog (276503 => 276504)
--- trunk/Tools/ChangeLog 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Tools/ChangeLog 2021-04-23 17:21:25 UTC (rev 276504)
@@ -1,3 +1,19 @@
+2021-04-23 Youenn Fablet <[email protected]>
+
+ Fix KVO for camera/microphone capture state WKWebView API
+ https://bugs.webkit.org/show_bug.cgi?id=224922
+ <rdar://problem/77008199>
+
+ Reviewed by Eric Carlson.
+
+ Add tests for capture state API.
+
+ * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
+ (-[MediaCaptureObserver observeValueForKeyPath:ofObject:change:context:]):
+ (TestWebKitAPI::waitUntilCameraState):
+ (TestWebKitAPI::waitUntilMicrophoneState):
+ (TestWebKitAPI::TEST):
+
2021-04-22 Tyler Wilcock <[email protected]>
[css-counter-styles] Parse @counter-style descriptors
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm (276503 => 276504)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm 2021-04-23 17:04:53 UTC (rev 276503)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm 2021-04-23 17:21:25 UTC (rev 276504)
@@ -88,6 +88,29 @@
- (WKPageRef)_pageForTesting;
@end
+static bool cameraCaptureStateChange;
+static bool microphoneCaptureStateChange;
+static WKMediaCaptureState cameraCaptureState;
+static WKMediaCaptureState microphoneCaptureState;
+
+@interface MediaCaptureObserver : NSObject
+@end
+
+@implementation MediaCaptureObserver
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context
+{
+ EXPECT_TRUE([keyPath isEqualToString:NSStringFromSelector(@selector(cameraCaptureState))] || [keyPath isEqualToString:NSStringFromSelector(@selector(microphoneCaptureState))]);
+ EXPECT_TRUE([[object class] isEqual:[TestWKWebView class]]);
+ if ([keyPath isEqualToString:NSStringFromSelector(@selector(cameraCaptureState))]) {
+ cameraCaptureState = (WKMediaCaptureState)[[change objectForKey:NSKeyValueChangeNewKey] unsignedIntegerValue];
+ cameraCaptureStateChange = true;
+ return;
+ }
+ microphoneCaptureState = (WKMediaCaptureState)[[change objectForKey:NSKeyValueChangeNewKey] unsignedIntegerValue];
+ microphoneCaptureStateChange = true;
+}
+@end
+
namespace TestWebKitAPI {
static String wkMediaCaptureStateString(_WKMediaCaptureStateDeprecated flags)
@@ -191,6 +214,98 @@
});
}
+bool waitUntilCameraState(WKWebView *webView, WKMediaCaptureState expectedState)
+{
+ if (expectedState == cameraCaptureState)
+ return true;
+ TestWebKitAPI::Util::run(&cameraCaptureStateChange);
+ return expectedState == cameraCaptureState;
+}
+
+bool waitUntilMicrophoneState(WKWebView *webView, WKMediaCaptureState expectedState)
+{
+ if (expectedState == microphoneCaptureState)
+ return true;
+ TestWebKitAPI::Util::run(µphoneCaptureStateChange);
+ return expectedState == microphoneCaptureState;
+}
+
+TEST(WebKit2, CaptureMuteAPI)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto processPoolConfig = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+ auto preferences = [configuration preferences];
+ preferences._mediaCaptureRequiresSecureConnection = NO;
+ configuration.get()._mediaCaptureEnabled = YES;
+ preferences._mockCaptureDevicesEnabled = YES;
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get() processPoolConfiguration:processPoolConfig.get()]);
+ auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
+ [webView setUIDelegate:delegate.get()];
+
+ [webView _setMediaCaptureReportingDelayForTesting:0];
+
+ auto observer = adoptNS([[MediaCaptureObserver alloc] init]);
+ [webView addObserver:observer.get() forKeyPath:@"microphoneCaptureState" options:NSKeyValueObservingOptionNew context:nil];
+ [webView addObserver:observer.get() forKeyPath:@"cameraCaptureState" options:NSKeyValueObservingOptionNew context:nil];
+
+ cameraCaptureStateChange = false;
+ [webView loadTestPageNamed:@"getUserMedia"];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateActive));
+
+ cameraCaptureStateChange = false;
+ [webView setCameraCaptureState:WKMediaCaptureStateMuted completionHandler:nil];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateMuted));
+
+ cameraCaptureStateChange = false;
+ [webView setCameraCaptureState:WKMediaCaptureStateActive completionHandler:nil];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateActive));
+
+ cameraCaptureStateChange = false;
+ [webView stringByEvaluatingJavaScript:@"stop()"];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateNone));
+
+ microphoneCaptureStateChange = false;
+ [webView stringByEvaluatingJavaScript:@"captureAudio()"];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateActive));
+
+ microphoneCaptureStateChange = false;
+ [webView setMicrophoneCaptureState:WKMediaCaptureStateMuted completionHandler:nil];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateMuted));
+
+ microphoneCaptureStateChange = false;
+ [webView setMicrophoneCaptureState:WKMediaCaptureStateActive completionHandler:nil];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateActive));
+
+ microphoneCaptureStateChange = false;
+ [webView stringByEvaluatingJavaScript:@"stop()"];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateNone));
+
+ microphoneCaptureStateChange = false;
+ cameraCaptureStateChange = false;
+ [webView stringByEvaluatingJavaScript:@"captureAudioAndVideo()"];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateActive));
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateActive));
+
+ cameraCaptureStateChange = false;
+ [webView setCameraCaptureState:WKMediaCaptureStateMuted completionHandler:nil];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateMuted));
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateActive));
+
+ microphoneCaptureStateChange = false;
+ [webView setMicrophoneCaptureState:WKMediaCaptureStateMuted completionHandler:nil];
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateMuted));
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateActive));
+
+ microphoneCaptureStateChange = false;
+ cameraCaptureStateChange = false;
+ [webView stringByEvaluatingJavaScript:@"stop()"];
+ EXPECT_TRUE(waitUntilMicrophoneState(webView.get(), WKMediaCaptureStateNone));
+ EXPECT_TRUE(waitUntilCameraState(webView.get(), WKMediaCaptureStateNone));
+
+ [webView removeObserver:observer.get() forKeyPath:@"microphoneCaptureState"];
+ [webView removeObserver:observer.get() forKeyPath:@"cameraCaptureState"];
+}
+
TEST(WebKit2, CaptureStop)
{
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);