Title: [246002] trunk
Revision
246002
Author
you...@apple.com
Date
2019-05-31 16:49:31 -0700 (Fri, 31 May 2019)

Log Message

Add an option to mute audio capture automatically when page is not visible
https://bugs.webkit.org/show_bug.cgi?id=198307

Reviewed by Eric Carlson.

Source/WebCore:

Reuse video capture mechanism for audio capture.
In case document gets in the background, interrupt the audio track if the audio factory requires it.
CoreAudioCaptureSourceIOS requires the audio source be interrupted if the app has not the right background mode.
It also allows interrupting the audio capture based on a runtime flag.

Add a runtime flag to control this.
Internals API is used to set it for test purposes, off by default.
For regular cases, the runtime flag is set through web preferences.

Test: platform/ios/mediastream/audio-muted-in-background-tab.html

* dom/Document.cpp:
(WebCore::Document::notifyMediaCaptureOfVisibilityChanged):
* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::interruptAudioOnPageVisibilityChangeEnabled const):
(WebCore::RuntimeEnabledFeatures::setInterruptAudioOnPageVisibilityChangeEnabled):
* platform/mediastream/RealtimeMediaSourceCenter.cpp:
(WebCore::RealtimeMediaSourceCenter::RealtimeMediaSourceCenter):
(WebCore::RealtimeMediaSourceCenter::initializeShouldInterruptAudioOnPageVisibilityChange):
(WebCore::RealtimeMediaSourceCenter::setCapturePageState):
(WebCore::RealtimeMediaSourceCenter::visibilityDidChange):
* platform/mediastream/RealtimeMediaSourceCenter.h:
(WebCore::RealtimeMediaSourceCenter::shouldInterruptAudioOnPageVisibilityChange):
* platform/mediastream/RealtimeMediaSourceFactory.h:
(WebCore::AudioCaptureFactory::setAudioCapturePageState):
(WebCore::VideoCaptureFactory::setVideoCapturePageState):
* platform/mediastream/ios/CoreAudioCaptureSourceIOS.h:
* platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm:
(WebCore::CoreAudioCaptureSourceFactory::setAudioCapturePageState):
(WebCore::CoreAudioCaptureSourceFactoryIOS::shouldInterruptAudioOnPageVisibilityChange):
* platform/mediastream/mac/CoreAudioCaptureSource.h:
* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
(WebCore::RealtimeMediaSourceCenter::initializeShouldInterruptAudioOnPageVisibilityChange):
* testing/Internals.cpp:
(WebCore::Internals::resetToConsistentState):
(WebCore::Internals::setShouldInterruptAudioOnPageVisibilityChange):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Add API to set the new runtime flag.
Make source proxy factories implement this automatic muting.

* Shared/WebPreferences.yaml:
* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _interruptAudioOnPageVisibilityChangeEnabled]):
(-[WKPreferences _setInterruptAudioOnPageVisibilityChangeEnabled:]):
* UIProcess/API/Cocoa/WKPreferencesPrivate.h:
* WebProcess/cocoa/UserMediaCaptureManager.cpp:
(WebKit::UserMediaCaptureManager::setAudioCapturePageState):
(WebKit::UserMediaCaptureManager::setVideoCapturePageState):
* WebProcess/cocoa/UserMediaCaptureManager.h:

LayoutTests:

* platform/ios/mediastream/audio-muted-in-background-tab-expected.txt: Added.
* platform/ios/mediastream/audio-muted-in-background-tab.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246001 => 246002)


--- trunk/LayoutTests/ChangeLog	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/LayoutTests/ChangeLog	2019-05-31 23:49:31 UTC (rev 246002)
@@ -1,3 +1,13 @@
+2019-05-31  Youenn Fablet  <you...@apple.com>
+
+        Add an option to mute audio capture automatically when page is not visible
+        https://bugs.webkit.org/show_bug.cgi?id=198307
+
+        Reviewed by Eric Carlson.
+
+        * platform/ios/mediastream/audio-muted-in-background-tab-expected.txt: Added.
+        * platform/ios/mediastream/audio-muted-in-background-tab.html: Added.
+
 2019-05-31  Shawn Roberts  <srobe...@apple.com>
 
         Updating expectations for failing tests

Added: trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab-expected.txt (0 => 246002)


--- trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab-expected.txt	2019-05-31 23:49:31 UTC (rev 246002)
@@ -0,0 +1,7 @@
+
+PASS Setup stream 
+PASS Hide page, video and audio should be muted 
+PASS Show page, video and audio should be unmuted 
+PASS Hide and mute page, video and audio should be muted 
+PASS Show page, video and audio should remain muted 
+

Added: trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab.html (0 => 246002)


--- trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab.html	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/mediastream/audio-muted-in-background-tab.html	2019-05-31 23:49:31 UTC (rev 246002)
@@ -0,0 +1,72 @@
+
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>Don't unmute audio when a tab becomes visible unless it was muted when the tab was hidden</title>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+        <script>
+            let audioTrack;
+            let videoTrack;
+
+            promise_test((t) => {
+                if (window.testRunner)
+                    testRunner.setUserMediaPermission(true);
+                if (!window.internals)
+                    return Promise.reject("this test needs internals API");
+
+                internals.setShouldInterruptAudioOnPageVisibilityChange(true);
+
+                return navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then((stream) => {
+                    audioTrack = stream.getAudioTracks()[0];
+                    videoTrack = stream.getVideoTracks()[0];
+
+                    assert_false(audioTrack.muted, "audio track is active");
+                    assert_false(videoTrack.muted, "video track is active");
+                })
+
+                .then(() => {
+                    test(() => {
+                        if (window.internals)
+                            window.internals.setPageVisibility(false);
+                        assert_true(audioTrack.muted, "audio track is muted");
+                        assert_true(videoTrack.muted, "video track is muted");
+                    }, "Hide page, video and audio should be muted");
+                })
+
+                .then(() => {
+                    test(() => {
+                        if (window.internals)
+                            window.internals.setPageVisibility(true);
+                        assert_false(audioTrack.muted, "audio track is active");
+                        assert_false(videoTrack.muted, "video track is active");
+                    }, "Show page, video and audio should be unmuted");
+                })
+
+                .then(() => {
+                    test(() => {
+                        if (window.internals) {
+                            window.internals.setPageVisibility(false);
+                            window.internals.setPageMuted("capturedevices");
+                        }
+                        assert_true(audioTrack.muted, "audio track is muted");
+                        assert_true(videoTrack.muted, "video track is muted");
+                    }, "Hide and mute page, video and audio should be muted");
+                })
+
+                .then(() => {
+                    test(() => {
+                        if (window.internals)
+                            window.internals.setPageVisibility(true);
+                        assert_true(audioTrack.muted, "audio track is muted");
+                        assert_true(videoTrack.muted, "video track is muted");
+                    }, "Show page, video and audio should remain muted");
+                })
+            }, "Setup stream");
+
+        </script>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (246001 => 246002)


--- trunk/Source/WebCore/ChangeLog	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/ChangeLog	2019-05-31 23:49:31 UTC (rev 246002)
@@ -1,3 +1,49 @@
+2019-05-31  Youenn Fablet  <you...@apple.com>
+
+        Add an option to mute audio capture automatically when page is not visible
+        https://bugs.webkit.org/show_bug.cgi?id=198307
+
+        Reviewed by Eric Carlson.
+
+        Reuse video capture mechanism for audio capture.
+        In case document gets in the background, interrupt the audio track if the audio factory requires it.
+        CoreAudioCaptureSourceIOS requires the audio source be interrupted if the app has not the right background mode.
+        It also allows interrupting the audio capture based on a runtime flag.
+
+        Add a runtime flag to control this.
+        Internals API is used to set it for test purposes, off by default.
+        For regular cases, the runtime flag is set through web preferences.
+
+        Test: platform/ios/mediastream/audio-muted-in-background-tab.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::notifyMediaCaptureOfVisibilityChanged):
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::interruptAudioOnPageVisibilityChangeEnabled const):
+        (WebCore::RuntimeEnabledFeatures::setInterruptAudioOnPageVisibilityChangeEnabled):
+        * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+        (WebCore::RealtimeMediaSourceCenter::RealtimeMediaSourceCenter):
+        (WebCore::RealtimeMediaSourceCenter::initializeShouldInterruptAudioOnPageVisibilityChange):
+        (WebCore::RealtimeMediaSourceCenter::setCapturePageState):
+        (WebCore::RealtimeMediaSourceCenter::visibilityDidChange):
+        * platform/mediastream/RealtimeMediaSourceCenter.h:
+        (WebCore::RealtimeMediaSourceCenter::shouldInterruptAudioOnPageVisibilityChange):
+        * platform/mediastream/RealtimeMediaSourceFactory.h:
+        (WebCore::AudioCaptureFactory::setAudioCapturePageState):
+        (WebCore::VideoCaptureFactory::setVideoCapturePageState):
+        * platform/mediastream/ios/CoreAudioCaptureSourceIOS.h:
+        * platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm:
+        (WebCore::CoreAudioCaptureSourceFactory::setAudioCapturePageState):
+        (WebCore::CoreAudioCaptureSourceFactoryIOS::shouldInterruptAudioOnPageVisibilityChange):
+        * platform/mediastream/mac/CoreAudioCaptureSource.h:
+        * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+        (WebCore::RealtimeMediaSourceCenter::initializeShouldInterruptAudioOnPageVisibilityChange):
+        * testing/Internals.cpp:
+        (WebCore::Internals::resetToConsistentState):
+        (WebCore::Internals::setShouldInterruptAudioOnPageVisibilityChange):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-05-31  Geoffrey Garen  <gga...@apple.com>
 
         Some WeakPtr typedef cleanup

Modified: trunk/Source/WebCore/SourcesCocoa.txt (246001 => 246002)


--- trunk/Source/WebCore/SourcesCocoa.txt	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/SourcesCocoa.txt	2019-05-31 23:49:31 UTC (rev 246002)
@@ -542,6 +542,7 @@
 platform/mediastream/mac/RealtimeIncomingAudioSourceCocoa.cpp
 platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm
 platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp
+platform/mediastream/mac/RealtimeMediaSourceCenterMac.mm
 platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp
 platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp
 platform/mediastream/mac/ScreenDisplayCaptureSourceMac.mm

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (246001 => 246002)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-31 23:49:31 UTC (rev 246002)
@@ -7278,6 +7278,7 @@
 		4162A44F101145AE00DFF3ED /* DedicatedWorkerGlobalScope.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DedicatedWorkerGlobalScope.idl; sourceTree = "<group>"; };
 		4162A4551011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
 		4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDedicatedWorkerGlobalScope.h; sourceTree = "<group>"; };
+		416CE4A4229DF12E00A8A686 /* RealtimeMediaSourceCenterMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RealtimeMediaSourceCenterMac.mm; sourceTree = "<group>"; };
 		416D759F20C6441300D02D2C /* NetworkLoadInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkLoadInformation.h; sourceTree = "<group>"; };
 		416E0B37209BC3C2004A95D9 /* FetchIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchIdentifier.h; sourceTree = "<group>"; };
 		416E29A5102FA962007FC14E /* WorkerReportingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerReportingProxy.h; sourceTree = "<group>"; };
@@ -15882,6 +15883,7 @@
 				5CDD833A1E4324BB00621E83 /* RealtimeIncomingVideoSourceCocoa.h */,
 				5CDD83391E4324BB00621E83 /* RealtimeIncomingVideoSourceCocoa.mm */,
 				4A0FFAA31AAF5EF60062803B /* RealtimeMediaSourceCenterMac.cpp */,
+				416CE4A4229DF12E00A8A686 /* RealtimeMediaSourceCenterMac.mm */,
 				41103AA71E39790A00769F14 /* RealtimeOutgoingAudioSourceCocoa.cpp */,
 				41103AA81E39790A00769F14 /* RealtimeOutgoingAudioSourceCocoa.h */,
 				5CDD833B1E4324BB00621B83 /* RealtimeOutgoingVideoSourceCocoa.cpp */,
@@ -16386,8 +16388,6 @@
 		115CFA9A208BC140001E6991 /* inlineformatting */ = {
 			isa = PBXGroup;
 			children = (
-				6F0CD694229ED32700C5994E /* InlineLine.h */,
-				6F0CD692229ED31900C5994E /* InlineLine.cpp */,
 				6FE7DDDD20EC6E8B008B5B4E /* text */,
 				6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */,
 				6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */,
@@ -16398,6 +16398,8 @@
 				1123AFDD209ABBBA00736ACC /* InlineInvalidation.cpp */,
 				1123AFDC209ABBBA00736ACC /* InlineInvalidation.h */,
 				6FE7CFA02177EEF1005B1573 /* InlineItem.h */,
+				6F0CD692229ED31900C5994E /* InlineLine.cpp */,
+				6F0CD694229ED32700C5994E /* InlineLine.h */,
 				6FB47E612277425A00C7BCB0 /* InlineLineBox.h */,
 				6FE198132178397B00446F08 /* InlineLineBreaker.cpp */,
 				6FE198152178397C00446F08 /* InlineLineBreaker.h */,
@@ -28191,7 +28193,6 @@
 				714C7C661FDAD2A100F2BEE1 /* AnimationPlaybackEvent.h in Headers */,
 				714C7C671FDAD2A900F2BEE1 /* AnimationPlaybackEventInit.h in Headers */,
 				71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */,
-				6F0CD695229ED32700C5994E /* InlineLine.h in Headers */,
 				0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */,
 				57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */,
 				57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */,
@@ -29497,6 +29498,7 @@
 				11310CF820BA4A6A0065A8D0 /* InlineInvalidation.h in Headers */,
 				6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */,
 				BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */,
+				6F0CD695229ED32700C5994E /* InlineLine.h in Headers */,
 				6FB47E632277425A00C7BCB0 /* InlineLineBox.h in Headers */,
 				6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */,
 				AA4C3A770B2B1679002334A2 /* InlineStyleSheetOwner.h in Headers */,

Modified: trunk/Source/WebCore/dom/Document.cpp (246001 => 246002)


--- trunk/Source/WebCore/dom/Document.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/dom/Document.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -7648,7 +7648,7 @@
     if (!page())
         return;
 
-    RealtimeMediaSourceCenter::singleton().setVideoCapturePageState(hidden(), page()->isMediaCaptureMuted());
+    RealtimeMediaSourceCenter::singleton().setCapturePageState(hidden(), page()->isMediaCaptureMuted());
 #endif
 }
 

Modified: trunk/Source/WebCore/page/RuntimeEnabledFeatures.h (246001 => 246002)


--- trunk/Source/WebCore/page/RuntimeEnabledFeatures.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/page/RuntimeEnabledFeatures.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -357,6 +357,9 @@
     bool pageAtRuleSupportEnabled() const { return m_pageAtRuleSupportEnabled; }
     void setPageAtRuleSupportEnabled(bool isEnabled) { m_pageAtRuleSupportEnabled = isEnabled; }
 
+    bool interruptAudioOnPageVisibilityChangeEnabled() const { return m_interruptAudioOnPageVisibilityChangeEnabled; }
+    void setInterruptAudioOnPageVisibilityChangeEnabled(bool enabled) { m_interruptAudioOnPageVisibilityChangeEnabled = enabled; }
+
     WEBCORE_EXPORT static RuntimeEnabledFeatures& sharedFeatures();
 
 private:
@@ -540,6 +543,7 @@
     bool m_isITPFirstPartyWebsiteDataRemovalEnabled { false };
 
     bool m_referrerPolicyAttributeEnabled { false };
+    bool m_interruptAudioOnPageVisibilityChangeEnabled { false };
 
     friend class WTF::NeverDestroyed<RuntimeEnabledFeatures>;
 };

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -38,6 +38,7 @@
 #include "CaptureDeviceManager.h"
 #include "Logging.h"
 #include "MediaStreamPrivate.h"
+#include "RuntimeEnabledFeatures.h"
 #include <wtf/SHA1.h>
 
 namespace WebCore {
@@ -262,8 +263,10 @@
     validHandler(WTFMove(audioDevices), WTFMove(videoDevices), WTFMove(deviceIdentifierHashSalt));
 }
 
-void RealtimeMediaSourceCenter::setVideoCapturePageState(bool interrupted, bool pageMuted)
+void RealtimeMediaSourceCenter::setCapturePageState(bool interrupted, bool pageMuted)
 {
+    if (RuntimeEnabledFeatures::sharedFeatures().interruptAudioOnPageVisibilityChangeEnabled())
+        audioCaptureFactory().setAudioCapturePageState(interrupted, pageMuted);
     videoCaptureFactory().setVideoCapturePageState(interrupted, pageMuted);
 }
 
@@ -317,6 +320,13 @@
     return m_displayCaptureFactoryOverride ? *m_displayCaptureFactoryOverride : defaultDisplayCaptureFactory();
 }
 
+#if !PLATFORM(COCOA)
+bool RealtimeMediaSourceCenter::shouldInterruptAudioOnPageVisibilityChange()
+{
+    return false;
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -86,10 +86,12 @@
 
     WEBCORE_EXPORT void setDevicesChangedObserver(std::function<void()>&&);
 
-    void setVideoCapturePageState(bool, bool);
+    void setCapturePageState(bool interrupted, bool pageMuted);
 
     void captureDevicesChanged();
 
+    WEBCORE_EXPORT static bool shouldInterruptAudioOnPageVisibilityChange();
+
 private:
     RealtimeMediaSourceCenter();
     friend class NeverDestroyed<RealtimeMediaSourceCenter>;
@@ -113,6 +115,8 @@
     AudioCaptureFactory* m_audioCaptureFactoryOverride { nullptr };
     VideoCaptureFactory* m_videoCaptureFactoryOverride { nullptr };
     DisplayCaptureFactory* m_displayCaptureFactoryOverride { nullptr };
+
+    bool m_shouldInterruptAudioOnPageVisibilityChange { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -57,6 +57,11 @@
     virtual ~AudioCaptureFactory() = default;
     virtual CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*) = 0;
     virtual CaptureDeviceManager& audioCaptureDeviceManager() = 0;
+    virtual void setAudioCapturePageState(bool interrupted, bool pageMuted)
+    {
+        UNUSED_PARAM(interrupted);
+        UNUSED_PARAM(pageMuted);
+    }
 
 protected:
     AudioCaptureFactory() = default;
@@ -71,7 +76,11 @@
     virtual ~VideoCaptureFactory() = default;
     virtual CaptureSourceOrError createVideoCaptureSource(const CaptureDevice&, String&&, const MediaConstraints*) = 0;
     virtual CaptureDeviceManager& videoCaptureDeviceManager() = 0;
-    virtual void setVideoCapturePageState(bool, bool) { }
+    virtual void setVideoCapturePageState(bool interrupted, bool pageMuted)
+    {
+        UNUSED_PARAM(interrupted);
+        UNUSED_PARAM(pageMuted);
+    }
 
 protected:
     VideoCaptureFactory() = default;
@@ -82,7 +91,6 @@
     virtual ~DisplayCaptureFactory() = default;
     virtual CaptureSourceOrError createDisplayCaptureSource(const CaptureDevice&, const MediaConstraints*) = 0;
     virtual CaptureDeviceManager& displayCaptureDeviceManager() = 0;
-    virtual void setDisplayCapturePageState(bool , bool) { }
 
 protected:
     DisplayCaptureFactory() = default;

Modified: trunk/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/ios/CoreAudioCaptureSourceIOS.mm	2019-05-31 23:49:31 UTC (rev 246002)
@@ -126,6 +126,12 @@
     return factory.get();
 }
 
+void CoreAudioCaptureSourceFactory::setAudioCapturePageState(bool interrupted, bool pageMuted)
+{
+    if (auto* activeSource = this->activeSource())
+        activeSource->setInterrupted(interrupted, pageMuted);
 }
 
+}
+
 #endif // ENABLE(MEDIA_STREAM) && PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -142,6 +142,9 @@
     }
 
     CaptureDeviceManager& audioCaptureDeviceManager() final;
+#if PLATFORM(IOS_FAMILY)
+    void setAudioCapturePageState(bool interrupted, bool pageMuted) final;
+#endif
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (246001 => 246002)


--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -38,6 +38,7 @@
 #include "DisplayCaptureManagerCocoa.h"
 #include "Logging.h"
 #include "MediaStreamPrivate.h"
+#include "RuntimeEnabledFeatures.h"
 #include "ScreenDisplayCaptureSourceMac.h"
 #include "WindowDisplayCaptureSourceMac.h"
 #include <wtf/MainThread.h>

Copied: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.mm (from rev 245999, trunk/Source/WebKit/Scripts/PreferencesTemplates/WebPreferencesStoreDefaultsMap.cpp.erb) (0 => 246002)


--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.mm	2019-05-31 23:49:31 UTC (rev 246002)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RealtimeMediaSourceCenter.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+namespace WebCore {
+
+bool RealtimeMediaSourceCenter::shouldInterruptAudioOnPageVisibilityChange()
+{
+#if PLATFORM(IOS)
+    NSArray *modes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
+    if (!modes)
+        return true;
+    
+    int modesCount = [modes count];
+    for (int i = 0; i < modesCount; i++) {
+        if ([[modes objectAtIndex:i] isEqual: @"audio"])
+            return false;
+    }
+    return true;
+#else
+    return false;
+#endif
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp (246001 => 246002)


--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -96,7 +96,7 @@
 
 private:
 #if PLATFORM(IOS_FAMILY)
-    void setVideoCapturePageState(bool interrupted, bool pageMuted)
+    void setVideoCapturePageState(bool interrupted, bool pageMuted) final
     {
         if (activeSource())
             activeSource()->setInterrupted(interrupted, pageMuted);
@@ -139,6 +139,13 @@
         return MockRealtimeAudioSource::create(String { device.persistentId() }, String { device.label() }, WTFMove(hashSalt), constraints);
     }
 private:
+#if PLATFORM(IOS_FAMILY)
+    void setAudioCapturePageState(bool interrupted, bool pageMuted) final
+    {
+        if (activeSource())
+            activeSource()->setInterrupted(interrupted, pageMuted);
+    }
+#endif
     CaptureDeviceManager& audioCaptureDeviceManager() final { return MockRealtimeMediaSourceCenter::singleton().audioCaptureDeviceManager(); }
 };
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (246001 => 246002)


--- trunk/Source/WebCore/testing/Internals.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/testing/Internals.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -532,6 +532,10 @@
     page.setFullscreenControlsHidden(false);
 
     MediaEngineConfigurationFactory::disableMock();
+
+#if ENABLE(MEDIA_STREAM)
+    RuntimeEnabledFeatures::sharedFeatures().setInterruptAudioOnPageVisibilityChangeEnabled(false);
+#endif
 }
 
 Internals::Internals(Document& document)
@@ -1502,6 +1506,10 @@
 #endif
 
 #if ENABLE(MEDIA_STREAM)
+void Internals::setShouldInterruptAudioOnPageVisibilityChange(bool shouldInterrupt)
+{
+    RuntimeEnabledFeatures::sharedFeatures().setInterruptAudioOnPageVisibilityChangeEnabled(shouldInterrupt);
+}
 
 void Internals::setMockMediaCaptureDevicesEnabled(bool enabled)
 {

Modified: trunk/Source/WebCore/testing/Internals.h (246001 => 246002)


--- trunk/Source/WebCore/testing/Internals.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/testing/Internals.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -516,6 +516,7 @@
 #endif
 
 #if ENABLE(MEDIA_STREAM)
+    void setShouldInterruptAudioOnPageVisibilityChange(bool);
     void setMockMediaCaptureDevicesEnabled(bool);
     void setMediaCaptureRequiresSecureConnection(bool);
     void setCustomPrivateRecorderCreator();

Modified: trunk/Source/WebCore/testing/Internals.idl (246001 => 246002)


--- trunk/Source/WebCore/testing/Internals.idl	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebCore/testing/Internals.idl	2019-05-31 23:49:31 UTC (rev 246002)
@@ -672,6 +672,7 @@
     [Conditional=WEB_RTC] void setH264HardwareEncoderAllowed(boolean allowed);
     [Conditional=WEB_RTC] void applyRotationForOutgoingVideoSources(RTCPeerConnection connection);
 
+    [Conditional=MEDIA_STREAM] void setShouldInterruptAudioOnPageVisibilityChange(boolean shouldInterrupt);
     [Conditional=MEDIA_STREAM] void setCameraMediaStreamTrackOrientation(MediaStreamTrack track, short orientation);
     [Conditional=MEDIA_STREAM] void observeMediaStreamTrack(MediaStreamTrack track);
     [Conditional=MEDIA_STREAM] Promise<ImageData> grabNextMediaStreamTrackFrame();

Modified: trunk/Source/WebKit/ChangeLog (246001 => 246002)


--- trunk/Source/WebKit/ChangeLog	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/ChangeLog	2019-05-31 23:49:31 UTC (rev 246002)
@@ -1,3 +1,23 @@
+2019-05-31  Youenn Fablet  <you...@apple.com>
+
+        Add an option to mute audio capture automatically when page is not visible
+        https://bugs.webkit.org/show_bug.cgi?id=198307
+
+        Reviewed by Eric Carlson.
+
+        Add API to set the new runtime flag.
+        Make source proxy factories implement this automatic muting.
+
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _interruptAudioOnPageVisibilityChangeEnabled]):
+        (-[WKPreferences _setInterruptAudioOnPageVisibilityChangeEnabled:]):
+        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
+        * WebProcess/cocoa/UserMediaCaptureManager.cpp:
+        (WebKit::UserMediaCaptureManager::setAudioCapturePageState):
+        (WebKit::UserMediaCaptureManager::setVideoCapturePageState):
+        * WebProcess/cocoa/UserMediaCaptureManager.h:
+
 2019-05-31  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [iOS] Autocorrection menu font is Times New Roman when using font-family: UICTFontTextStyle*

Modified: trunk/Source/WebKit/Scripts/PreferencesTemplates/WebPreferencesStoreDefaultsMap.cpp.erb (246001 => 246002)


--- trunk/Source/WebKit/Scripts/PreferencesTemplates/WebPreferencesStoreDefaultsMap.cpp.erb	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/Scripts/PreferencesTemplates/WebPreferencesStoreDefaultsMap.cpp.erb	2019-05-31 23:49:31 UTC (rev 246002)
@@ -36,6 +36,7 @@
 // FIXME: These should added via options in WebPreferences.yaml, rather than hardcoded.
 #include <WebCore/DeprecatedGlobalSettings.h>
 #include <WebCore/LibWebRTCProvider.h>
+#include <WebCore/RealtimeMediaSourceCenter.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/Settings.h>
 #include <WebCore/TextEncodingRegistry.h>

Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (246001 => 246002)


--- trunk/Source/WebKit/Shared/WebPreferences.yaml	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml	2019-05-31 23:49:31 UTC (rev 246002)
@@ -545,6 +545,12 @@
   webcoreBinding: RuntimeEnabledFeatures
   condition: ENABLE(WEB_RTC)
 
+InterruptAudioOnPageVisibilityChangeEnabled:
+  type: bool
+  defaultValue: WebCore::RealtimeMediaSourceCenter::shouldInterruptAudioOnPageVisibilityChange()
+  webcoreBinding: RuntimeEnabledFeatures
+  condition: ENABLE(MEDIA_STREAM)
+
 WebRTCUnifiedPlanEnabled:
   type: bool
   defaultValue: true

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm (246001 => 246002)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm	2019-05-31 23:49:31 UTC (rev 246002)
@@ -649,6 +649,16 @@
     _preferences->setInactiveMediaCaptureSteamRepromptIntervalInMinutes(interval);
 }
 
+- (BOOL)_interruptAudioOnPageVisibilityChangeEnabled
+{
+    return _preferences->interruptAudioOnPageVisibilityChangeEnabled();
+}
+
+- (void)_setInterruptAudioOnPageVisibilityChangeEnabled:(BOOL)enabled
+{
+    _preferences->setInterruptAudioOnPageVisibilityChangeEnabled(enabled);
+}
+
 - (BOOL)_enumeratingAllNetworkInterfacesEnabled
 {
     return _preferences->enumeratingAllNetworkInterfacesEnabled();

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h (246001 => 246002)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -120,6 +120,7 @@
 @property (nonatomic, setter=_setICECandidateFilteringEnabled:) BOOL _iceCandidateFilteringEnabled WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
 @property (nonatomic, setter=_setWebRTCLegacyAPIEnabled:) BOOL _webRTCLegacyAPIEnabled WK_API_AVAILABLE(macos(10.13), ios(11.0));
 @property (nonatomic, setter=_setInactiveMediaCaptureSteamRepromptIntervalInMinutes:) double _inactiveMediaCaptureSteamRepromptIntervalInMinutes WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
+@property (nonatomic, setter=_setInterruptAudioOnPageVisibilityChangeEnabled:) BOOL _interruptAudioOnPageVisibilityChangeEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @property (nonatomic, setter=_setJavaScriptCanAccessClipboard:) BOOL _javaScriptCanAccessClipboard WK_API_AVAILABLE(macos(10.13), ios(11.0));
 @property (nonatomic, setter=_setDOMPasteAllowed:) BOOL _domPasteAllowed WK_API_AVAILABLE(macos(10.13), ios(11.0));

Modified: trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp (246001 => 246002)


--- trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp	2019-05-31 23:49:31 UTC (rev 246002)
@@ -366,6 +366,20 @@
         source->applyConstraintsFailed(WTFMove(failedConstraint), WTFMove(message));
 }
 
+#if PLATFORM(IOS_FAMILY)
+void UserMediaCaptureManager::setAudioCapturePageState(bool interrupted, bool pageMuted)
+{
+    if (auto* activeSource = static_cast<AudioCaptureFactory*>(this)->activeSource())
+        activeSource->setInterrupted(interrupted, pageMuted);
 }
 
+void UserMediaCaptureManager::setVideoCapturePageState(bool interrupted, bool pageMuted)
+{
+    if (auto* activeSource = static_cast<VideoCaptureFactory*>(this)->activeSource())
+        activeSource->setInterrupted(interrupted, pageMuted);
+}
 #endif
+
+}
+
+#endif

Modified: trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h (246001 => 246002)


--- trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h	2019-05-31 23:49:14 UTC (rev 246001)
+++ trunk/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h	2019-05-31 23:49:31 UTC (rev 246002)
@@ -79,6 +79,11 @@
     WebCore::CaptureDeviceManager& videoCaptureDeviceManager() final { return m_noOpCaptureDeviceManager; }
     WebCore::CaptureDeviceManager& displayCaptureDeviceManager() final { return m_noOpCaptureDeviceManager; }
 
+#if PLATFORM(IOS_FAMILY)
+    void setAudioCapturePageState(bool interrupted, bool pageMuted) final;
+    void setVideoCapturePageState(bool interrupted, bool pageMuted) final;
+#endif
+
     // IPC::MessageReceiver
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to