Title: [243958] trunk
Revision
243958
Author
jer.no...@apple.com
Date
2019-04-05 18:08:50 -0700 (Fri, 05 Apr 2019)

Log Message

[Cocoa] Deactivate the audio session before the WebProcess suspends.
https://bugs.webkit.org/show_bug.cgi?id=196658

Reviewed by Eric Carlson.

Source/WebCore:

Test: platform/mac/media/audio-session-deactivated-when-suspended.html

Deactivate the audio session when we are notified that the session will suspend.

Drive-by fix: don't try to begin playback when the process is suspended.

* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback):
(WebCore::PlatformMediaSessionManager::processWillSuspend):
(WebCore::PlatformMediaSessionManager::processDidResume):
* platform/audio/PlatformMediaSessionManager.h:
(WebCore::PlatformMediaSessionManager::processIsSuspended const):
* testing/InternalSettings.cpp:
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setShouldDeactivateAudioSession):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:
* testing/Internals.cpp:
(WebCore::Internals::processWillSuspend):
(WebCore::Internals::processDidResume):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Notify the PlatformMediaSessionManager when the process suspends or resumes.

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::actualPrepareToSuspend):
(WebKit::WebProcess::cancelPrepareToSuspend):
(WebKit::WebProcess::processDidResume):

LayoutTests:

* platform/mac/media/audio-session-deactivated-when-suspended-expected.txt: Added.
* platform/mac/media/audio-session-deactivated-when-suspended.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (243957 => 243958)


--- trunk/LayoutTests/ChangeLog	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/LayoutTests/ChangeLog	2019-04-06 01:08:50 UTC (rev 243958)
@@ -1,3 +1,13 @@
+2019-04-05  Jer Noble  <jer.no...@apple.com>
+
+        [Cocoa] Deactivate the audio session before the WebProcess suspends.
+        https://bugs.webkit.org/show_bug.cgi?id=196658
+
+        Reviewed by Eric Carlson.
+
+        * platform/mac/media/audio-session-deactivated-when-suspended-expected.txt: Added.
+        * platform/mac/media/audio-session-deactivated-when-suspended.html: Added.
+
 2019-04-05  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: TestSuite test cases should have their own timeout to ensure tests fail with output instead of timeout by test runner

Added: trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended-expected.txt (0 => 243958)


--- trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended-expected.txt	2019-04-06 01:08:50 UTC (rev 243958)
@@ -0,0 +1,13 @@
+
+RUN(internals.settings.setShouldDeactivateAudioSession(true))
+RUN(video = document.querySelector("video"))
+RUN(video.src = "" "../../../media/content/test"))
+RUN(video.play())
+EVENT(playing)
+EXPECTED (internals.audioSessionActive() == 'true') OK
+RUN(internals.processWillSuspend())
+EXPECTED (internals.audioSessionActive() == 'false') OK
+RUN(internals.processDidResume())
+EXPECTED (internals.audioSessionActive() == 'true') OK
+END OF TEST
+

Added: trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended.html (0 => 243958)


--- trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/media/audio-session-deactivated-when-suspended.html	2019-04-06 01:08:50 UTC (rev 243958)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>audio-session-deactivated-when-suspended</title>
+	<script src=""
+	<script src=""
+	<script>
+	window.addEventListener('load', async event => {
+		run('internals.settings.setShouldDeactivateAudioSession(true)');
+		run('video = document.querySelector("video")');
+		run('video.src = "" "../../../media/content/test")');
+		runWithKeyDown('video.play()');
+		await waitFor(video, 'playing');
+		testExpected('internals.audioSessionActive()', true);
+		run('internals.processWillSuspend()');
+		testExpected('internals.audioSessionActive()', false);
+		run('internals.processDidResume()');
+		testExpected('internals.audioSessionActive()', true);
+		endTest();
+	});
+	</script>
+</head>
+<body>
+	<video controls></video>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (243957 => 243958)


--- trunk/Source/WebCore/ChangeLog	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/ChangeLog	2019-04-06 01:08:50 UTC (rev 243958)
@@ -1,3 +1,34 @@
+2019-04-05  Jer Noble  <jer.no...@apple.com>
+
+        [Cocoa] Deactivate the audio session before the WebProcess suspends.
+        https://bugs.webkit.org/show_bug.cgi?id=196658
+
+        Reviewed by Eric Carlson.
+
+        Test: platform/mac/media/audio-session-deactivated-when-suspended.html
+
+        Deactivate the audio session when we are notified that the session will suspend.
+
+        Drive-by fix: don't try to begin playback when the process is suspended.
+
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback):
+        (WebCore::PlatformMediaSessionManager::processWillSuspend):
+        (WebCore::PlatformMediaSessionManager::processDidResume):
+        * platform/audio/PlatformMediaSessionManager.h:
+        (WebCore::PlatformMediaSessionManager::processIsSuspended const):
+        * testing/InternalSettings.cpp:
+        (WebCore::InternalSettings::Backup::Backup):
+        (WebCore::InternalSettings::Backup::restoreTo):
+        (WebCore::InternalSettings::setShouldDeactivateAudioSession):
+        * testing/InternalSettings.h:
+        * testing/InternalSettings.idl:
+        * testing/Internals.cpp:
+        (WebCore::Internals::processWillSuspend):
+        (WebCore::Internals::processDidResume):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2019-04-05  Sihui Liu  <sihui_...@apple.com>
 
         [iOS] Web process gets suspended while holding locked database files

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (243957 => 243958)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2019-04-06 01:08:50 UTC (rev 243958)
@@ -204,18 +204,25 @@
 
 bool PlatformMediaSessionManager::sessionWillBeginPlayback(PlatformMediaSession& session)
 {
-    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
-    
     setCurrentSession(session);
 
     PlatformMediaSession::MediaType sessionType = session.mediaType();
     SessionRestrictions restrictions = m_restrictions[sessionType];
-    if (session.state() == PlatformMediaSession::Interrupted && restrictions & InterruptedPlaybackNotPermitted)
+    if (session.state() == PlatformMediaSession::Interrupted && restrictions & InterruptedPlaybackNotPermitted) {
+        ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning false because session.state() is Interrupted, and InterruptedPlaybackNotPermitted");
         return false;
+    }
 
+    if (m_processIsSuspended) {
+        ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning false because process is suspended");
+        return false;
+    }
+
 #if USE(AUDIO_SESSION)
-    if (activeAudioSessionRequired() && !AudioSession::sharedSession().tryToSetActive(true))
+    if (activeAudioSessionRequired() && !AudioSession::sharedSession().tryToSetActive(true)) {
+        ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning false failed to set active AudioSession");
         return false;
+    }
 
     m_becameActive = true;
 #endif
@@ -232,6 +239,7 @@
             oneSession.pauseSession();
     });
 
+    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning true");
     return true;
 }
     
@@ -362,6 +370,36 @@
     });
 }
 
+void PlatformMediaSessionManager::processWillSuspend()
+{
+    if (m_processIsSuspended)
+        return;
+    m_processIsSuspended = true;
+
+#if USE(AUDIO_SESSION)
+    if (m_becameActive && shouldDeactivateAudioSession()) {
+        AudioSession::sharedSession().tryToSetActive(false);
+        ALWAYS_LOG(LOGIDENTIFIER, "tried to set inactive AudioSession");
+        m_becameActive = false;
+    }
+#endif
+}
+
+void PlatformMediaSessionManager::processDidResume()
+{
+    if (!m_processIsSuspended)
+        return;
+    m_processIsSuspended = false;
+
+#if USE(AUDIO_SESSION)
+    if (!m_becameActive && activeAudioSessionRequired()) {
+        m_becameActive = AudioSession::sharedSession().tryToSetActive(true);
+        ALWAYS_LOG(LOGIDENTIFIER, "tried to set active AudioSession, ", m_becameActive ? "succeeded" : "failed");
+    }
+#endif
+}
+
+
 void PlatformMediaSessionManager::sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession& session)
 {
     if (!m_isApplicationInBackground || !(m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted))

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (243957 => 243958)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2019-04-06 01:08:50 UTC (rev 243958)
@@ -57,6 +57,7 @@
     static void updateNowPlayingInfoIfNecessary();
 
     WEBCORE_EXPORT static void setShouldDeactivateAudioSession(bool);
+    WEBCORE_EXPORT static bool shouldDeactivateAudioSession();
 
     virtual ~PlatformMediaSessionManager() = default;
 
@@ -84,6 +85,8 @@
     WEBCORE_EXPORT void applicationDidBecomeActive() const;
     WEBCORE_EXPORT void applicationWillEnterForeground(bool suspendedUnderLock) const;
     WEBCORE_EXPORT void applicationDidEnterBackground(bool suspendedUnderLock) const;
+    WEBCORE_EXPORT void processWillSuspend();
+    WEBCORE_EXPORT void processDidResume();
 
     void stopAllMediaPlaybackForDocument(const Document*);
     WEBCORE_EXPORT void stopAllMediaPlaybackForProcess();
@@ -141,6 +144,8 @@
 
     AudioHardwareListener* audioHardwareListener() { return m_audioHardwareListener.get(); }
 
+    bool processIsSuspended() const { return m_processIsSuspended; }
+
 #if !RELEASE_LOG_DISABLED
     const Logger& logger() const final { return m_logger; }
     const void* logIdentifier() const final { return nullptr; }
@@ -166,8 +171,6 @@
     void systemWillSleep() override;
     void systemDidWake() override;
 
-    static bool shouldDeactivateAudioSession();
-
     SessionRestrictions m_restrictions[PlatformMediaSession::MediaStreamCapturingAudio + 1];
     mutable Vector<PlatformMediaSession*> m_sessions;
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
@@ -183,6 +186,7 @@
     mutable bool m_isApplicationInBackground { false };
     bool m_willIgnoreSystemInterruptions { false };
     mutable int m_iteratingOverSessions { 0 };
+    bool m_processIsSuspended { false };
 
 #if USE(AUDIO_SESSION)
     bool m_becameActive { false };

Modified: trunk/Source/WebCore/testing/InternalSettings.cpp (243957 => 243958)


--- trunk/Source/WebCore/testing/InternalSettings.cpp	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/InternalSettings.cpp	2019-04-06 01:08:50 UTC (rev 243958)
@@ -36,6 +36,7 @@
 #include "LocaleToScriptMapping.h"
 #include "Page.h"
 #include "PageGroup.h"
+#include "PlatformMediaSessionManager.h"
 #include "RenderTheme.h"
 #include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
@@ -97,6 +98,7 @@
 #if ENABLE(ACCESSIBILITY_EVENTS)
     , m_accessibilityEventsEnabled(settings.accessibilityEventsEnabled())
 #endif
+    , m_shouldDeactivateAudioSession(PlatformMediaSessionManager::shouldDeactivateAudioSession())
     , m_userInterfaceDirectionPolicy(settings.userInterfaceDirectionPolicy())
     , m_systemLayoutDirection(settings.systemLayoutDirection())
     , m_pdfImageCachingPolicy(settings.pdfImageCachingPolicy())
@@ -202,6 +204,7 @@
     FontCache::singleton().setShouldMockBoldSystemFontForAccessibility(m_shouldMockBoldSystemFontForAccessibility);
     settings.setFrameFlattening(m_frameFlattening);
     settings.setIncompleteImageBorderEnabled(m_incompleteImageBorderEnabled);
+    PlatformMediaSessionManager::setShouldDeactivateAudioSession(m_shouldDeactivateAudioSession);
 #if ENABLE(ACCESSIBILITY_EVENTS)
     settings.setAccessibilityEventsEnabled(m_accessibilityEventsEnabled);
 #endif
@@ -972,6 +975,11 @@
     return RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled();
 }
 
+void InternalSettings::setShouldDeactivateAudioSession(bool should)
+{
+    PlatformMediaSessionManager::setShouldDeactivateAudioSession(should);
+}
+
 // If you add to this class, make sure that you update the Backup class for test reproducability!
 
 }

Modified: trunk/Source/WebCore/testing/InternalSettings.h (243957 => 243958)


--- trunk/Source/WebCore/testing/InternalSettings.h	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/InternalSettings.h	2019-04-06 01:08:50 UTC (rev 243958)
@@ -129,6 +129,8 @@
 
     static bool webAnimationsCSSIntegrationEnabled();
 
+    void setShouldDeactivateAudioSession(bool);
+
 private:
     explicit InternalSettings(Page*);
 
@@ -196,6 +198,7 @@
 #if ENABLE(ACCESSIBILITY_EVENTS)
         bool m_accessibilityEventsEnabled;
 #endif
+        bool m_shouldDeactivateAudioSession;
         UserInterfaceDirectionPolicy m_userInterfaceDirectionPolicy;
         TextDirection m_systemLayoutDirection;
         PDFImageCachingPolicy m_pdfImageCachingPolicy;

Modified: trunk/Source/WebCore/testing/InternalSettings.idl (243957 => 243958)


--- trunk/Source/WebCore/testing/InternalSettings.idl	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/InternalSettings.idl	2019-04-06 01:08:50 UTC (rev 243958)
@@ -115,5 +115,6 @@
     [EnabledAtRuntime=WebAnimations] boolean webAnimationsCSSIntegrationEnabled();
 
     [MayThrowException] void setAccessibilityEventsEnabled(boolean enabled);
+    void setShouldDeactivateAudioSession(boolean shouldDeactivate);
 };
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (243957 => 243958)


--- trunk/Source/WebCore/testing/Internals.cpp	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/Internals.cpp	2019-04-06 01:08:50 UTC (rev 243958)
@@ -4971,4 +4971,14 @@
     localFrame->loader().setAlwaysAllowLocalWebarchive(alwaysAllowLocalWebarchive);
 }
 
+void Internals::processWillSuspend()
+{
+    PlatformMediaSessionManager::sharedManager().processWillSuspend();
+}
+
+void Internals::processDidResume()
+{
+    PlatformMediaSessionManager::sharedManager().processDidResume();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.h (243957 => 243958)


--- trunk/Source/WebCore/testing/Internals.h	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/Internals.h	2019-04-06 01:08:50 UTC (rev 243958)
@@ -803,6 +803,8 @@
     Vector<CookieData> getCookies() const;
 
     void setAlwaysAllowLocalWebarchive(bool);
+    void processWillSuspend();
+    void processDidResume();
 
 private:
     explicit Internals(Document&);

Modified: trunk/Source/WebCore/testing/Internals.idl (243957 => 243958)


--- trunk/Source/WebCore/testing/Internals.idl	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebCore/testing/Internals.idl	2019-04-06 01:08:50 UTC (rev 243958)
@@ -739,4 +739,7 @@
     sequence<CookieData> getCookies();
 
     void setAlwaysAllowLocalWebarchive(boolean alwaysAllowLocalWebarchive);
+
+    void processWillSuspend();
+    void processDidResume();
 };

Modified: trunk/Source/WebKit/ChangeLog (243957 => 243958)


--- trunk/Source/WebKit/ChangeLog	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebKit/ChangeLog	2019-04-06 01:08:50 UTC (rev 243958)
@@ -1,3 +1,17 @@
+2019-04-05  Jer Noble  <jer.no...@apple.com>
+
+        [Cocoa] Deactivate the audio session before the WebProcess suspends.
+        https://bugs.webkit.org/show_bug.cgi?id=196658
+
+        Reviewed by Eric Carlson.
+
+        Notify the PlatformMediaSessionManager when the process suspends or resumes.
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::actualPrepareToSuspend):
+        (WebKit::WebProcess::cancelPrepareToSuspend):
+        (WebKit::WebProcess::processDidResume):
+
 2019-04-05  Sihui Liu  <sihui_...@apple.com>
 
         [iOS] Web process gets suspended while holding locked database files

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (243957 => 243958)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-04-06 01:02:44 UTC (rev 243957)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2019-04-06 01:08:50 UTC (rev 243958)
@@ -1453,6 +1453,7 @@
 
 #if ENABLE(VIDEO)
     suspendAllMediaBuffering();
+    PlatformMediaSessionManager::sharedManager().processWillSuspend();
 #endif
 
     if (!m_suppressMemoryPressureHandler)
@@ -1519,6 +1520,7 @@
 #endif
 
 #if ENABLE(VIDEO)
+    PlatformMediaSessionManager::sharedManager().processDidResume();
     resumeAllMediaBuffering();
 #endif
 
@@ -1592,6 +1594,7 @@
 #endif
 
 #if ENABLE(VIDEO)
+    PlatformMediaSessionManager::sharedManager().processDidResume();
     resumeAllMediaBuffering();
 #endif
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to