Title: [276504] trunk
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(&microphoneCaptureStateChange);
+    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]);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to