Title: [218140] trunk/Source/WebCore
Revision
218140
Author
eric.carl...@apple.com
Date
2017-06-12 14:56:55 -0700 (Mon, 12 Jun 2017)

Log Message

[MediaStream iOS] If a capturing tab is muted while it is in the background, it can not be unmuted
https://bugs.webkit.org/show_bug.cgi?id=173268
<rdar://problem/32259809>

Reviewed by Jer Noble.

No new tests, tested manually.

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::startProducingData): Mute the private stream if page capture is muted.
(WebCore::MediaStream::mediaState): Set new interrupted state.

* dom/Document.cpp:
(WebCore::Document::notifyMediaCaptureOfVisibilityChanged): Don't track "muted for visibility"
state, let the source center deal with it.
* dom/Document.h:

* page/MediaProducer.h: Add bits for interrupted audio and video capture.

* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::RealtimeMediaSource): Drive-by fix: delete m_suppressNotifications,
it isn't used.
(WebCore::RealtimeMediaSource::setInterrupted): New. Mute capture when an interruption begins,
and unmute when it ends in an unmuted page.
(WebCore::RealtimeMediaSource::setMuted): Do not unmute if interrupted.
(WebCore::RealtimeMediaSource::settingsDidChange): Don't check m_suppressNotifications, it is
never set.
* platform/mediastream/RealtimeMediaSource.h:

* platform/mediastream/RealtimeMediaSourceCenter.cpp:
(WebCore::RealtimeMediaSourceCenter::setVideoCapturePageState): Renamed from
setVideoCaptureMutedForPageVisibility.
(WebCore::RealtimeMediaSourceCenter::setVideoCaptureMutedForPageVisibility): Deleted.
* platform/mediastream/RealtimeMediaSourceCenter.h:

* platform/mediastream/mac/AVMediaCaptureSource.h:
* platform/mediastream/mac/AVMediaCaptureSource.mm:
(WebCore::AVMediaCaptureSource::stopProducingData): Clear m_interruption because the session
has been deleted, so we will never get an "end interruption" notification.
(WebCore::AVMediaCaptureSource::captureSessionIsRunningDidChange): Don't return early if
the muted state needs to be updated.
(WebCore::AVMediaCaptureSource::captureSessionEndInterruption): Return early if the session
has been cleared.
(WebCore::AVMediaCaptureSource::interrupted): New.

* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSourceFactory::setVideoCapturePageState): Renamed from
setVideoCaptureMutedForPageVisibility.
(WebCore::AVVideoCaptureSourceFactory::setVideoCaptureMutedForPageVisibility): Deleted.

* platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSourceFactory::setVideoCapturePageState): Ditto.
(WebCore::MockRealtimeVideoSourceFactory::setVideoCaptureMutedForPageVisibility): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (218139 => 218140)


--- trunk/Source/WebCore/ChangeLog	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/ChangeLog	2017-06-12 21:56:55 UTC (rev 218140)
@@ -1,3 +1,59 @@
+2017-06-12  Eric Carlson  <eric.carl...@apple.com>
+
+        [MediaStream iOS] If a capturing tab is muted while it is in the background, it can not be unmuted
+        https://bugs.webkit.org/show_bug.cgi?id=173268
+        <rdar://problem/32259809>
+
+        Reviewed by Jer Noble.
+
+        No new tests, tested manually.
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::startProducingData): Mute the private stream if page capture is muted.
+        (WebCore::MediaStream::mediaState): Set new interrupted state.
+
+        * dom/Document.cpp:
+        (WebCore::Document::notifyMediaCaptureOfVisibilityChanged): Don't track "muted for visibility"
+        state, let the source center deal with it.
+        * dom/Document.h:
+
+        * page/MediaProducer.h: Add bits for interrupted audio and video capture.
+
+        * platform/mediastream/RealtimeMediaSource.cpp:
+        (WebCore::RealtimeMediaSource::RealtimeMediaSource): Drive-by fix: delete m_suppressNotifications,
+        it isn't used.
+        (WebCore::RealtimeMediaSource::setInterrupted): New. Mute capture when an interruption begins,
+        and unmute when it ends in an unmuted page.
+        (WebCore::RealtimeMediaSource::setMuted): Do not unmute if interrupted.
+        (WebCore::RealtimeMediaSource::settingsDidChange): Don't check m_suppressNotifications, it is
+        never set.
+        * platform/mediastream/RealtimeMediaSource.h:
+
+        * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+        (WebCore::RealtimeMediaSourceCenter::setVideoCapturePageState): Renamed from 
+        setVideoCaptureMutedForPageVisibility.
+        (WebCore::RealtimeMediaSourceCenter::setVideoCaptureMutedForPageVisibility): Deleted.
+        * platform/mediastream/RealtimeMediaSourceCenter.h:
+
+        * platform/mediastream/mac/AVMediaCaptureSource.h:
+        * platform/mediastream/mac/AVMediaCaptureSource.mm:
+        (WebCore::AVMediaCaptureSource::stopProducingData): Clear m_interruption because the session
+        has been deleted, so we will never get an "end interruption" notification.
+        (WebCore::AVMediaCaptureSource::captureSessionIsRunningDidChange): Don't return early if
+        the muted state needs to be updated.
+        (WebCore::AVMediaCaptureSource::captureSessionEndInterruption): Return early if the session
+        has been cleared.
+        (WebCore::AVMediaCaptureSource::interrupted): New.
+
+        * platform/mediastream/mac/AVVideoCaptureSource.mm:
+        (WebCore::AVVideoCaptureSourceFactory::setVideoCapturePageState): Renamed from 
+        setVideoCaptureMutedForPageVisibility.
+        (WebCore::AVVideoCaptureSourceFactory::setVideoCaptureMutedForPageVisibility): Deleted.
+
+        * platform/mock/MockRealtimeVideoSource.cpp:
+        (WebCore::MockRealtimeVideoSourceFactory::setVideoCapturePageState): Ditto.
+        (WebCore::MockRealtimeVideoSourceFactory::setVideoCaptureMutedForPageVisibility): Deleted.
+
 2017-06-12  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebCrypto] Remove experimental feature flag of SubtleCrypto

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp (218139 => 218140)


--- trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStream.cpp	2017-06-12 21:56:55 UTC (rev 218140)
@@ -297,8 +297,10 @@
     m_isProducingData = true;
 
     m_mediaSession->canProduceAudioChanged();
+    m_private->startProducingData();
 
-    m_private->startProducingData();
+    if (document->page()->isMediaCaptureMuted())
+        m_private->setCaptureTracksMuted(true);
 }
 
 void MediaStream::stopProducingData()
@@ -336,23 +338,34 @@
 {
     MediaStateFlags state = IsNotPlaying;
 
-    if (!m_isActive)
+    if (!m_isActive || !document() || !document()->page())
         return state;
 
+    bool pageCaptureMuted = document()->page()->isMediaCaptureMuted();
     for (const auto& track : m_trackSet.values()) {
         if (!track->isCaptureTrack() || track->ended())
             continue;
 
         if (track->source().type() == RealtimeMediaSource::Type::Audio) {
-            if (track->muted())
+            if (track->source().interrupted() && !pageCaptureMuted)
+                state |= HasInterruptedAudioCaptureDevice;
+            else if (track->muted())
                 state |= HasMutedAudioCaptureDevice;
-            else if (m_isProducingData && m_private->isProducingData())
+            else if (m_isProducingData && m_private->isProducingData()) {
                 state |= HasActiveAudioCaptureDevice;
+                ASSERT(!track->source().interrupted());
+                ASSERT(!track->muted());
+            }
         } else {
-            if (track->muted())
+            if (track->source().interrupted() && !pageCaptureMuted)
+                state |= HasInterruptedVideoCaptureDevice;
+            else if (track->muted())
                 state |= HasMutedVideoCaptureDevice;
-            else if (m_isProducingData && m_private->isProducingData())
+            else if (m_isProducingData && m_private->isProducingData()) {
                 state |= HasActiveVideoCaptureDevice;
+                ASSERT(!track->source().interrupted());
+                ASSERT(!track->muted());
+            }
         }
     }
 

Modified: trunk/Source/WebCore/dom/Document.cpp (218139 => 218140)


--- trunk/Source/WebCore/dom/Document.cpp	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/dom/Document.cpp	2017-06-12 21:56:55 UTC (rev 218140)
@@ -7082,16 +7082,10 @@
 void Document::notifyMediaCaptureOfVisibilityChanged()
 {
 #if ENABLE(MEDIA_STREAM)
-    if (!page() || page()->isMediaCaptureMuted()) {
-        m_videoCaptureMutedForVisibilityChange = false;
+    if (!page())
         return;
-    }
 
-    if (!hidden() && !m_videoCaptureMutedForVisibilityChange)
-        return;
-
-    m_videoCaptureMutedForVisibilityChange = hidden();
-    RealtimeMediaSourceCenter::singleton().setVideoCaptureMutedForPageVisibility(m_videoCaptureMutedForVisibilityChange);
+    RealtimeMediaSourceCenter::singleton().setVideoCapturePageState(hidden(), page()->isMediaCaptureMuted());
 #endif
 }
 

Modified: trunk/Source/WebCore/dom/Document.h (218139 => 218140)


--- trunk/Source/WebCore/dom/Document.h	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/dom/Document.h	2017-06-12 21:56:55 UTC (rev 218140)
@@ -1778,7 +1778,6 @@
     HashSet<HTMLMediaElement*> m_mediaStreamStateChangeElements;
     String m_idHashSalt;
     bool m_hasHadActiveMediaStreamTrack { false };
-    bool m_videoCaptureMutedForVisibilityChange { false };
 #endif
 
 #ifndef NDEBUG

Modified: trunk/Source/WebCore/page/MediaProducer.h (218139 => 218140)


--- trunk/Source/WebCore/page/MediaProducer.h	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/page/MediaProducer.h	2017-06-12 21:56:55 UTC (rev 218140)
@@ -46,6 +46,8 @@
         HasActiveVideoCaptureDevice = 1 << 12,
         HasMutedAudioCaptureDevice = 1 << 13,
         HasMutedVideoCaptureDevice = 1 << 14,
+        HasInterruptedAudioCaptureDevice = 1 << 15,
+        HasInterruptedVideoCaptureDevice = 1 << 15,
     };
     typedef unsigned MediaStateFlags;
 

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp	2017-06-12 21:56:55 UTC (rev 218140)
@@ -57,7 +57,6 @@
     if (m_id.isEmpty())
         m_id = createCanonicalUUIDString();
     m_persistentID = m_id;
-    m_suppressNotifications = false;
 }
 
 void RealtimeMediaSource::addObserver(RealtimeMediaSource::Observer& observer)
@@ -75,12 +74,28 @@
         stop();
 }
 
+void RealtimeMediaSource::setInterrupted(bool interrupted, bool pageMuted)
+{
+    if (interrupted == m_interrupted)
+        return;
+
+    m_interrupted = interrupted;
+    if (!interrupted && pageMuted)
+        return;
+
+    setMuted(interrupted);
+}
+
 void RealtimeMediaSource::setMuted(bool muted)
 {
     if (muted)
         stop();
-    else
+    else {
+        if (interrupted())
+            return;
+
         start();
+    }
 
     notifyMutedChange(muted);
 }
@@ -116,7 +131,7 @@
 {
     ASSERT(isMainThread());
 
-    if (m_pendingSettingsDidChangeNotification || m_suppressNotifications)
+    if (m_pendingSettingsDidChangeNotification)
         return;
 
     m_pendingSettingsDidChangeNotification = true;

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h	2017-06-12 21:56:55 UTC (rev 218140)
@@ -120,7 +120,7 @@
     public:
         virtual ~VideoCaptureFactory() = default;
         virtual CaptureSourceOrError createVideoCaptureSource(const String& videoDeviceID, const MediaConstraints*) = 0;
-        virtual void setVideoCaptureMutedForPageVisibility(bool) { }
+        virtual void setVideoCapturePageState(bool, bool) { }
 
     protected:
         VideoCaptureFactory() = default;
@@ -143,6 +143,9 @@
 
     bool muted() const { return m_muted; }
     void setMuted(bool);
+
+    virtual bool interrupted() const { return m_interrupted; }
+    virtual void setInterrupted(bool, bool);
     
     bool enabled() const { return m_enabled; }
     void setEnabled(bool);
@@ -265,8 +268,8 @@
 
     bool m_echoCancellation { false };
     bool m_pendingSettingsDidChangeNotification { false };
-    bool m_suppressNotifications { true };
     bool m_isProducingData { false };
+    bool m_interrupted { false };
 };
 
 struct CaptureSourceOrError {

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp	2017-06-12 21:56:55 UTC (rev 218140)
@@ -334,9 +334,9 @@
     validHandler(WTFMove(audioSourceIds), WTFMove(videoSourceIds), WTFMove(deviceIdentifierHashSalt));
 }
 
-void RealtimeMediaSourceCenter::setVideoCaptureMutedForPageVisibility(bool shouldMute)
+void RealtimeMediaSourceCenter::setVideoCapturePageState(bool interrupted, bool pageMuted)
 {
-    videoFactory().setVideoCaptureMutedForPageVisibility(shouldMute);
+    videoFactory().setVideoCapturePageState(interrupted, pageMuted);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h	2017-06-12 21:56:55 UTC (rev 218140)
@@ -100,7 +100,7 @@
     void removeDevicesChangedObserver(DevicesChangedObserverToken);
     void captureDevicesChanged();
 
-    void setVideoCaptureMutedForPageVisibility(bool);
+    void setVideoCapturePageState(bool, bool);
 
 protected:
     RealtimeMediaSourceCenter();

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h	2017-06-12 21:56:55 UTC (rev 218140)
@@ -96,6 +96,8 @@
 
     bool isCaptureSource() const final { return true; }
 
+    bool interrupted() const final;
+
     void initializeSettings();
     void initializeCapabilities();
 

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm	2017-06-12 21:56:55 UTC (rev 218140)
@@ -188,6 +188,7 @@
     if ([m_session isRunning])
         [m_session stopRunning];
 
+    m_interruption = InterruptionReason::None;
 #if PLATFORM(IOS)
     m_session = nullptr;
 #endif
@@ -264,7 +265,7 @@
 void AVMediaCaptureSource::captureSessionIsRunningDidChange(bool state)
 {
     scheduleDeferredTask([this, state] {
-        if (state == m_isRunning)
+        if ((state == m_isRunning) && (state == !muted()))
             return;
 
         m_isRunning = state;
@@ -293,7 +294,7 @@
     InterruptionReason reason = m_interruption;
 
     m_interruption = InterruptionReason::None;
-    if (reason != InterruptionReason::VideoNotAllowedInSideBySide || m_isRunning)
+    if (reason != InterruptionReason::VideoNotAllowedInSideBySide || m_isRunning || !m_session)
         return;
 
     [m_session startRunning];
@@ -317,6 +318,14 @@
     return nullptr;
 }
 
+bool AVMediaCaptureSource::interrupted() const
+{
+    if (m_interruption != InterruptionReason::None)
+        return true;
+
+    return RealtimeMediaSource::interrupted();
+}
+
 NSArray<NSString*>* sessionKVOProperties()
 {
     static NSArray* keys = [@[@"running"] retain];

Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (218139 => 218140)


--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm	2017-06-12 21:56:55 UTC (rev 218140)
@@ -125,10 +125,10 @@
 
 #if PLATFORM(IOS)
 private:
-    void setVideoCaptureMutedForPageVisibility(bool shouldMute)
+    void setVideoCapturePageState(bool interrupted, bool pageMuted)
     {
         if (activeSource())
-            activeSource()->setMuted(shouldMute);
+            activeSource()->setInterrupted(interrupted, pageMuted);
     }
 #endif
 };

Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp (218139 => 218140)


--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp	2017-06-12 21:35:25 UTC (rev 218139)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp	2017-06-12 21:56:55 UTC (rev 218140)
@@ -63,10 +63,10 @@
     }
 #if PLATFORM(IOS)
 private:
-    void setVideoCaptureMutedForPageVisibility(bool shouldMute)
+    void setVideoCapturePageState(bool interrupted, bool pageMuted)
     {
         if (activeSource())
-            activeSource()->setMuted(shouldMute);
+            activeSource()->setInterrupted(interrupted, pageMuted);
     }
 #endif
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to