Title: [214976] trunk
Revision
214976
Author
[email protected]
Date
2017-04-05 16:22:20 -0700 (Wed, 05 Apr 2017)

Log Message

[MediaStream] Host application should be able to mute and unmute media streams
https://bugs.webkit.org/show_bug.cgi?id=170519
<rdar://problem/31174326>

Reviewed by Youenn Fablet.

Source/WebCore:

No new tests, fast/mediastream/MediaStream-page-muted.html was updated.

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::~MediaStream): Fix a typo.
(WebCore::MediaStream::pageMutedStateDidChange): Don't store muted state, let the private
stream store it.
(WebCore::MediaStream::mediaState): Deal with new muted state flags.
* Modules/mediastream/MediaStream.h:

* dom/Document.cpp:
(WebCore::Document::prepareForDestruction): Clear media state before the frame is cleared.

* page/MediaProducer.h: Add muted flags.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): The display layer
should not be visible when the video track is muted.

* platform/mediastream/MediaStreamPrivate.cpp:
(WebCore::MediaStreamPrivate::addTrack): Mute the new track if necessary.
(WebCore::MediaStreamPrivate::startProducingData): Do nothing when muted.
(WebCore::MediaStreamPrivate::setExternallyMuted): New, mute/unmute tracks.
* platform/mediastream/MediaStreamPrivate.h:

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::setMuted): Start/stop producing data.

* testing/Internals.cpp:
(WebCore::Internals::pageMediaState): Support new media stream muted flags.

Source/WebKit2:

* UIProcess/API/C/WKPage.cpp:
(WKPageGetMediaState): Support new media stream state flags.
* UIProcess/API/C/WKPagePrivate.h:
* UIProcess/API/Cocoa/WKWebViewPrivate.h: Ditto.
* UIProcess/Cocoa/UIDelegate.mm: Ditto.

LayoutTests:

* fast/mediastream/MediaStream-page-muted-expected.txt:
* fast/mediastream/MediaStream-page-muted.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (214975 => 214976)


--- trunk/LayoutTests/ChangeLog	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/ChangeLog	2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,14 @@
+2017-04-05  Eric Carlson  <[email protected]>
+
+        [MediaStream] Host application should be able to mute and unmute media streams
+        https://bugs.webkit.org/show_bug.cgi?id=170519
+        <rdar://problem/31174326>
+
+        Reviewed by Youenn Fablet.
+
+        * fast/mediastream/MediaStream-page-muted-expected.txt:
+        * fast/mediastream/MediaStream-page-muted.html:
+
 2017-04-05  Javier Fernandez  <[email protected]>
 
         [css-align] Implement the place-items shorthand

Modified: trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt (214975 => 214976)


--- trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-page-muted-expected.txt	2017-04-05 23:22:20 UTC (rev 214976)
@@ -15,7 +15,10 @@
 EVENT: mute
 PASS muteChangedEvent.target.muted is true
 
-PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became false
+PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became false
+PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became false
 
 *** Unmuting capture devices
 EVENT: unmute
@@ -23,7 +26,10 @@
 EVENT: unmute
 PASS muteChangedEvent.target.muted is false
 
-PASS window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice') became true
+PASS window.internals.pageMediaState().includes(HasActiveAudioCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasActiveVideoCaptureDevice) became true
+PASS window.internals.pageMediaState().includes(HasMutedAudioCaptureDevice) became false
+PASS window.internals.pageMediaState().includes(HasMutedVideoCaptureDevice) became false
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html (214975 => 214976)


--- trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/LayoutTests/fast/mediastream/MediaStream-page-muted.html	2017-04-05 23:22:20 UTC (rev 214976)
@@ -27,8 +27,37 @@
 
                 if (++eventCount == 2) {
                     debug("");
-                    let shouldBeActive = muteChangedEvent.type == "mute" ? "false" : "true";
-                    shouldBecomeEqual("window.internals.pageMediaState().includes('HasActiveAudioCaptureDevice') && window.internals.pageMediaState().includes('HasActiveVideoCaptureDevice')", shouldBeActive, nextStep);
+                    
+                    let activeState = muteChangedEvent.type == "mute" ? "Muted" : "Active";
+                    let inactiveState = muteChangedEvent.type == "mute" ? "Active" : "Muted";
+                    let retryCount = 0;
+                    let retryInterval = 100;
+                    let maximumRetryCount = 20 * 1000 / retryInterval;
+                    let test = () => {
+
+                        if (window.internals.pageMediaState().includes(`Has${activeState}AudioCaptureDevice`) 
+                            && window.internals.pageMediaState().includes(`Has${activeState}VideoCaptureDevice`)
+                            && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)
+                            && !window.internals.pageMediaState().includes(`Has${inactiveState}VideoCaptureDevice`)) {
+
+                            testPassed(`window.internals.pageMediaState().includes(Has${activeState}AudioCaptureDevice) became true`);
+                            testPassed(`window.internals.pageMediaState().includes(Has${activeState}VideoCaptureDevice) became true`);
+                            testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}AudioCaptureDevice) became false`);
+                            testPassed(`window.internals.pageMediaState().includes(Has${inactiveState}VideoCaptureDevice) became false`);
+                            
+                            nextStep()
+                            return;
+                        }
+                        
+                        if (++retryCount > maximumRetryCount) {
+                            testFailed(`Page muted state failed to change after ${maximumRetryCount / 1000} seconds`);
+                            return;
+                        }
+                        
+                        setTimeout(test, retryInterval);
+                    }
+
+                    setTimeout(test, 0);
                 }
             }
             

Modified: trunk/Source/WebCore/ChangeLog (214975 => 214976)


--- trunk/Source/WebCore/ChangeLog	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/ChangeLog	2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,41 @@
+2017-04-05  Eric Carlson  <[email protected]>
+
+        [MediaStream] Host application should be able to mute and unmute media streams
+        https://bugs.webkit.org/show_bug.cgi?id=170519
+        <rdar://problem/31174326>
+
+        Reviewed by Youenn Fablet.
+
+        No new tests, fast/mediastream/MediaStream-page-muted.html was updated.
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::~MediaStream): Fix a typo.
+        (WebCore::MediaStream::pageMutedStateDidChange): Don't store muted state, let the private
+        stream store it.
+        (WebCore::MediaStream::mediaState): Deal with new muted state flags.
+        * Modules/mediastream/MediaStream.h:
+
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction): Clear media state before the frame is cleared.
+
+        * page/MediaProducer.h: Add muted flags.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): The display layer
+        should not be visible when the video track is muted.
+
+        * platform/mediastream/MediaStreamPrivate.cpp:
+        (WebCore::MediaStreamPrivate::addTrack): Mute the new track if necessary.
+        (WebCore::MediaStreamPrivate::startProducingData): Do nothing when muted.
+        (WebCore::MediaStreamPrivate::setExternallyMuted): New, mute/unmute tracks.
+        * platform/mediastream/MediaStreamPrivate.h:
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::setMuted): Start/stop producing data.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::pageMediaState): Support new media stream muted flags.
+
 2017-04-05  Andreas Kling  <[email protected]>
 
         Make inactive web processes behave as though under memory pressure.

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (214975 => 214976)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -104,7 +104,7 @@
 
 MediaStream::~MediaStream()
 {
-    // Set isActive to false immediately so an callbacks triggered by shutting down, e.g.
+    // Set isActive to false immediately so any callbacks triggered by shutting down, e.g.
     // mediaState(), are short circuited.
     m_isActive = false;
     MediaStreamRegistry::shared().unregisterStream(*this);
@@ -300,15 +300,7 @@
     if (!document)
         return;
 
-    bool pageMuted = document->page()->isMediaCaptureMuted();
-    if (m_externallyMuted == pageMuted)
-        return;
-
-    m_externallyMuted = pageMuted;
-    if (pageMuted)
-        stopProducingData();
-    else
-        startProducingData();
+    m_private->setMuted(document->page()->isMediaCaptureMuted());
 }
 
 MediaProducer::MediaStateFlags MediaStream::mediaState() const
@@ -320,14 +312,22 @@
 
     if (m_private->hasAudio()) {
         state |= HasAudioOrVideo;
-        if (m_private->hasCaptureAudioSource() && m_private->isProducingData())
-            state |= HasActiveAudioCaptureDevice;
+        if (m_private->hasCaptureAudioSource()) {
+            if (m_private->isProducingData())
+                state |= HasActiveAudioCaptureDevice;
+            else if (m_private->muted())
+                state |= HasMutedAudioCaptureDevice;
+        }
     }
 
     if (m_private->hasVideo()) {
         state |= HasAudioOrVideo;
-        if (m_private->hasCaptureVideoSource() && m_private->isProducingData())
-            state |= HasActiveVideoCaptureDevice;
+        if (m_private->hasCaptureVideoSource()) {
+            if (m_private->isProducingData())
+                state |= HasActiveVideoCaptureDevice;
+            else if (m_private->muted())
+                state |= HasMutedVideoCaptureDevice;
+        }
     }
 
     return state;

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.h (214975 => 214976)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.h	2017-04-05 23:22:20 UTC (rev 214976)
@@ -157,7 +157,6 @@
 
     bool m_isActive { false };
     bool m_isMuted { true };
-    bool m_externallyMuted { false };
     bool m_isWaitingUntilMediaCanStart { false };
 };
 

Modified: trunk/Source/WebCore/dom/Document.cpp (214975 => 214976)


--- trunk/Source/WebCore/dom/Document.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/dom/Document.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -2267,6 +2267,11 @@
 
     m_cachedResourceLoader->stopUnusedPreloadsTimer();
 
+    if (page() && m_mediaState != MediaProducer::IsNotPlaying) {
+        m_mediaState = MediaProducer::IsNotPlaying;
+        page()->updateIsPlayingMedia(HTMLMediaElementInvalidID);
+    }
+
     detachFromFrame();
 
     m_hasPreparedForDestruction = true;

Modified: trunk/Source/WebCore/page/MediaProducer.h (214975 => 214976)


--- trunk/Source/WebCore/page/MediaProducer.h	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/page/MediaProducer.h	2017-04-05 23:22:20 UTC (rev 214976)
@@ -44,6 +44,8 @@
         HasAudioOrVideo = 1 << 10,
         HasActiveAudioCaptureDevice = 1 << 11,
         HasActiveVideoCaptureDevice = 1 << 12,
+        HasMutedAudioCaptureDevice = 1 << 13,
+        HasMutedVideoCaptureDevice = 1 << 14,
     };
     typedef unsigned MediaStateFlags;
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (214975 => 214976)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2017-04-05 23:22:20 UTC (rev 214976)
@@ -950,7 +950,7 @@
         if (oldVideoTrack != m_activeVideoTrack)
             m_imagePainter.reset();
         ensureLayers();
-        m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer;
+        m_sampleBufferDisplayLayer.get().hidden = hideVideoLayer || m_displayMode < PausedImage;
         m_pendingSelectedTrackCheck = false;
         updateDisplayMode();
     });

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp (214975 => 214976)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -134,6 +134,9 @@
     if (m_trackSet.contains(track->id()))
         return;
 
+    if (m_muted)
+        track->stopProducingData();
+
     track->addObserver(*this);
     m_trackSet.add(track->id(), track);
 
@@ -162,6 +165,9 @@
 
 void MediaStreamPrivate::startProducingData()
 {
+    if (m_muted)
+        return;
+
     for (auto& track : m_trackSet.values())
         track->startProducingData();
 }
@@ -181,6 +187,18 @@
     return false;
 }
 
+void MediaStreamPrivate::setMuted(bool muted)
+{
+    if (m_muted == muted)
+        return;
+
+    m_muted = muted;
+    for (auto& track : m_trackSet.values()) {
+        if (track->isCaptureTrack())
+            track->setMuted(muted);
+    }
+}
+
 bool MediaStreamPrivate::hasVideo() const
 {
     for (auto& track : m_trackSet.values()) {

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h (214975 => 214976)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h	2017-04-05 23:22:20 UTC (rev 214976)
@@ -95,6 +95,8 @@
 
     bool hasVideo() const;
     bool hasAudio() const;
+
+    void setMuted(bool);
     bool muted() const;
 
     bool hasCaptureVideoSource() const;
@@ -134,6 +136,7 @@
     MediaStreamTrackPrivate* m_activeVideoTrack { nullptr };
     HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet;
     bool m_isActive { false };
+    bool m_muted { false };
 };
 
 typedef Vector<RefPtr<MediaStreamPrivate>> MediaStreamPrivateVector;

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (214975 => 214976)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -91,6 +91,13 @@
     if (stopped())
         return;
 
+    if (muted) {
+        // FIXME: We need to figure out how to guarantee that at least one black video frame is
+        // emitted after being muted.
+        stopProducingData();
+    } else
+        startProducingData();
+
     for (auto& observer : m_observers)
         observer->sourceMutedChanged();
 }

Modified: trunk/Source/WebCore/testing/Internals.cpp (214975 => 214976)


--- trunk/Source/WebCore/testing/Internals.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebCore/testing/Internals.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -3523,6 +3523,10 @@
         string.append("HasActiveAudioCaptureDevice,");
     if (state & MediaProducer::HasActiveVideoCaptureDevice)
         string.append("HasActiveVideoCaptureDevice,");
+    if (state & MediaProducer::HasMutedAudioCaptureDevice)
+        string.append("HasMutedAudioCaptureDevice,");
+    if (state & MediaProducer::HasMutedVideoCaptureDevice)
+        string.append("HasMutedVideoCaptureDevice,");
 
     if (string.isEmpty())
         string.append("IsNotPlaying");

Modified: trunk/Source/WebKit2/ChangeLog (214975 => 214976)


--- trunk/Source/WebKit2/ChangeLog	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/ChangeLog	2017-04-05 23:22:20 UTC (rev 214976)
@@ -1,3 +1,17 @@
+2017-04-05  Eric Carlson  <[email protected]>
+
+        [MediaStream] Host application should be able to mute and unmute media streams
+        https://bugs.webkit.org/show_bug.cgi?id=170519
+        <rdar://problem/31174326>
+
+        Reviewed by Youenn Fablet.
+
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageGetMediaState): Support new media stream state flags.
+        * UIProcess/API/C/WKPagePrivate.h:
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h: Ditto.
+        * UIProcess/Cocoa/UIDelegate.mm: Ditto.
+
 2017-04-05  Brady Eidson  <[email protected]>
 
         Refactor so WebsiteDataStores always have a StorageManager.

Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp (214975 => 214976)


--- trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp	2017-04-05 23:22:20 UTC (rev 214976)
@@ -2813,6 +2813,10 @@
         state |= kWKMediaHasActiveAudioCaptureDevice;
     if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
         state |= kWKMediaHasActiveVideoCaptureDevice;
+    if (coreState & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
+        state |= kWKMediaHasMutedAudioCaptureDevice;
+    if (coreState & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
+        state |= kWKMediaHasMutedVideoCaptureDevice;
 
     return state;
 }

Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h (214975 => 214976)


--- trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h	2017-04-05 23:22:20 UTC (rev 214976)
@@ -137,6 +137,8 @@
     kWKMediaIsPlayingVideo = 1 << 1,
     kWKMediaHasActiveAudioCaptureDevice = 1 << 2,
     kWKMediaHasActiveVideoCaptureDevice = 1 << 3,
+    kWKMediaHasMutedAudioCaptureDevice = 1 << 4,
+    kWKMediaHasMutedVideoCaptureDevice = 1 << 5,
 };
 typedef uint32_t WKMediaState;
 

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (214975 => 214976)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-04-05 23:22:20 UTC (rev 214976)
@@ -41,8 +41,10 @@
 
 typedef NS_OPTIONS(NSInteger, _WKMediaCaptureState) {
     _WKMediaCaptureStateNone = 0,
-    _WKMediaCaptureStateMicrophone = 1 << 0,
-    _WKMediaCaptureStateCamera = 1 << 1,
+    _WKMediaCaptureStateActiveMicrophone = 1 << 0,
+    _WKMediaCaptureStateActiveCamera = 1 << 1,
+    _WKMediaCaptureStateMutedMicrophone = 1 << 2,
+    _WKMediaCaptureStateMutedCamera = 1 << 3,
 } WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if !TARGET_OS_IPHONE

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm (214975 => 214976)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm	2017-04-05 23:12:46 UTC (rev 214975)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm	2017-04-05 23:22:20 UTC (rev 214976)
@@ -443,9 +443,13 @@
 
     _WKMediaCaptureState mediaCaptureState = _WKMediaCaptureStateNone;
     if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
-        mediaCaptureState |= _WKMediaCaptureStateMicrophone;
+        mediaCaptureState |= _WKMediaCaptureStateActiveMicrophone;
     if (state & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
-        mediaCaptureState |= _WKMediaCaptureStateCamera;
+        mediaCaptureState |= _WKMediaCaptureStateActiveCamera;
+    if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
+        mediaCaptureState |= _WKMediaCaptureStateMutedMicrophone;
+    if (state & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
+        mediaCaptureState |= _WKMediaCaptureStateMutedCamera;
 
     [(id <WKUIDelegatePrivate>)delegate _webView:webView mediaCaptureStateDidChange:mediaCaptureState];
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to