Skip to content
Permalink
Browse files
[iOS] pause video when a tab moves to the background on some devices
https://bugs.webkit.org/show_bug.cgi?id=141753
<rdar://problem/19814562>

Reviewed by Jer Noble.

Source/WebCore:

Test: media/video-background-tab-playback.html

* platform/audio/MediaSession.cpp:
(WebCore::MediaSession::clientDataBufferingTimerFired): Pause video when the element becomes
    hidden if the BackgroundTabPlaybackRestricted is set.

* platform/audio/MediaSessionManager.cpp:
(WebCore::MediaSessionManager::applicationWillEnterBackground): Rename BackgroundPlaybackNotPermitted
     to BackgroundProcessPlaybackRestricted.
(WebCore::MediaSessionManager::applicationWillEnterForeground): Ditto.
* platform/audio/MediaSessionManager.h:

* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::resetRestrictions): Set BackgroundTabPlaybackRestricted on
    devices with restricted memory. BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.

* testing/Internals.cpp:
(WebCore::Internals::setMediaSessionRestrictions): Add support for BackgroundTabPlaybackRestricted.
    BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.

LayoutTests:

* media/video-background-playback-expected.txt: BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.
* media/video-background-playback.html: Ditto.
* media/video-background-tab-playback-expected.txt: Added.
* media/video-background-tab-playback.html: Added.


Canonical link: https://commits.webkit.org/159775@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
eric-carlson committed Feb 18, 2015
1 parent d464276 commit 1f613e9cbc989a30aa26b109e2bb0e32a26c1350
@@ -1,3 +1,16 @@
2015-02-18 Eric Carlson <eric.carlson@apple.com>

[iOS] pause video when a tab moves to the background on some devices
https://bugs.webkit.org/show_bug.cgi?id=141753
<rdar://problem/19814562>

Reviewed by Jer Noble.

* media/video-background-playback-expected.txt: BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.
* media/video-background-playback.html: Ditto.
* media/video-background-tab-playback-expected.txt: Added.
* media/video-background-tab-playback.html: Added.

2015-02-16 David Hyatt <hyatt@apple.com>

Wrong element's style is used for text-decoration-style.
@@ -1,7 +1,7 @@

Test switching application state when <video> is not allowed to play in background.

RUN(internals.setMediaSessionRestrictions('video', 'BackgroundPlaybackNotPermitted'))
RUN(internals.setMediaSessionRestrictions('video', 'BackgroundProcessPlaybackRestricted'))

EVENT(canplaythrough)
EVENT(canplaythrough)
@@ -78,7 +78,7 @@
audio = elements[1];
audio.src = findMediaFile("audio", "content/silence");

run("internals.setMediaSessionRestrictions('video', 'BackgroundPlaybackNotPermitted')");
run("internals.setMediaSessionRestrictions('video', 'BackgroundProcessPlaybackRestricted')");
state = "foreground";
consoleWrite("");
}
@@ -0,0 +1,26 @@

Test tab with <video> moving to background when playback is not allowed in background.

RUN(internals.setMediaSessionRestrictions('video', 'BackgroundTabPlaybackRestricted'))

EVENT(canplaythrough)

RUN(video.play())
EVENT(playing)

** Simulate switching the tab to background, video should pause.
RUN(testRunner.setPageVisibility('hidden'))


** 100ms timer fired...
EXPECTED (video.paused == 'true') OK

** Simulate switch back to foreground, video should remain paused.
RUN(internals.applicationWillEnterForeground())


** 100ms timer fired...
EXPECTED (video.paused == 'true') OK

END OF TEST

@@ -0,0 +1,67 @@
<html>
<head>
<script src=media-file.js></script>
<script src=video-test.js></script>
<script>
var state = 0;

function checkState()
{
consoleWrite("<br>** 100ms timer fired...");
switch (state) {
case "background":
testExpected("video.paused", true);
state = "foreground";
consoleWrite("<br>** Simulate switch back to foreground, video should remain paused.");
run("internals.applicationWillEnterForeground()");
setTimeout(checkState, 100);
consoleWrite("");
break;
case "foreground":
testExpected("video.paused", true);
consoleWrite("");
testRunner.resetPageVisibility();
endTest();
break;
}
}

function playing(evt)
{
consoleWrite("<br>** Simulate switching the tab to background, video should pause.");
run("testRunner.setPageVisibility('hidden')");
setTimeout(checkState, 100);
state = "background";
consoleWrite("");
}

function canplaythrough(evt)
{
consoleWrite("");
run("video.play()");
}

function start()
{
if (!window.internals) {
failTest('This test requires window.internals.');
return;
}

findMediaElement();
video.src = findMediaFile("video", "content/test");
waitForEvent('canplaythrough', canplaythrough);
waitForEvent('playing', playing);

run("internals.setMediaSessionRestrictions('video', 'BackgroundTabPlaybackRestricted')");
state = "foreground";
consoleWrite("");
}
</script>
</head>

<body onload="start()">
<video controls></video>
<p>Test tab with &lt;video&gt; moving to background when playback is not allowed in background.</p>
</body>
</html>
@@ -1,3 +1,31 @@
2015-02-18 Eric Carlson <eric.carlson@apple.com>

[iOS] pause video when a tab moves to the background on some devices
https://bugs.webkit.org/show_bug.cgi?id=141753
<rdar://problem/19814562>

Reviewed by Jer Noble.

Test: media/video-background-tab-playback.html

* platform/audio/MediaSession.cpp:
(WebCore::MediaSession::clientDataBufferingTimerFired): Pause video when the element becomes
hidden if the BackgroundTabPlaybackRestricted is set.

* platform/audio/MediaSessionManager.cpp:
(WebCore::MediaSessionManager::applicationWillEnterBackground): Rename BackgroundPlaybackNotPermitted
to BackgroundProcessPlaybackRestricted.
(WebCore::MediaSessionManager::applicationWillEnterForeground): Ditto.
* platform/audio/MediaSessionManager.h:

* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::resetRestrictions): Set BackgroundTabPlaybackRestricted on
devices with restricted memory. BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.

* testing/Internals.cpp:
(WebCore::Internals::setMediaSessionRestrictions): Add support for BackgroundTabPlaybackRestricted.
BackgroundPlaybackNotPermitted -> BackgroundProcessPlaybackRestricted.

2015-02-16 David Hyatt <hyatt@apple.com>

Wrong element's style is used for text-decoration-style.
@@ -190,7 +190,16 @@ void MediaSession::visibilityChanged()

void MediaSession::clientDataBufferingTimerFired()
{
LOG(Media, "MediaSession::visibilityChanged(%p)- visible = %s", this, m_client.elementIsHidden() ? "false" : "true");

updateClientDataBuffering();

if (m_state != Playing || !m_client.elementIsHidden())
return;

MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType());
if ((restrictions & MediaSessionManager::BackgroundTabPlaybackRestricted) == MediaSessionManager::BackgroundTabPlaybackRestricted)
pauseSession();
}

void MediaSession::updateClientDataBuffering()
@@ -270,7 +270,7 @@ void MediaSessionManager::applicationWillEnterBackground() const
LOG(Media, "MediaSessionManager::applicationWillEnterBackground");
Vector<MediaSession*> sessions = m_sessions;
for (auto* session : sessions) {
if (m_restrictions[session->mediaType()] & BackgroundPlaybackNotPermitted)
if (m_restrictions[session->mediaType()] & BackgroundProcessPlaybackRestricted)
session->beginInterruption(MediaSession::EnteringBackground);
}
}
@@ -280,7 +280,7 @@ void MediaSessionManager::applicationWillEnterForeground() const
LOG(Media, "MediaSessionManager::applicationWillEnterForeground");
Vector<MediaSession*> sessions = m_sessions;
for (auto* session : sessions) {
if (m_restrictions[session->mediaType()] & BackgroundPlaybackNotPermitted)
if (m_restrictions[session->mediaType()] & BackgroundProcessPlaybackRestricted)
session->endInterruption(MediaSession::MayResumePlaying);
}
}
@@ -62,7 +62,8 @@ class MediaSessionManager : private RemoteCommandListenerClient, private SystemS
InlineVideoPlaybackRestricted = 1 << 1,
MetadataPreloadingNotPermitted = 1 << 2,
AutoPreloadingNotPermitted = 1 << 3,
BackgroundPlaybackNotPermitted = 1 << 4,
BackgroundProcessPlaybackRestricted = 1 << 4,
BackgroundTabPlaybackRestricted = 1 << 5,
};
typedef unsigned SessionRestrictions;

@@ -33,6 +33,7 @@
#import "MediaPlayerSPI.h"
#import "MediaSession.h"
#import "SoftLinking.h"
#import "SystemMemory.h"
#import "WebCoreSystemInterface.h"
#import "WebCoreThreadRun.h"
#import <AVFoundation/AVAudioSession.h>
@@ -127,6 +128,8 @@ - (void)stopMonitoringAirPlayRoutes;

void MediaSessionManageriOS::resetRestrictions()
{
static const size_t systemMemoryRequiredForVideoInBackgroundTabs = 1024 * 1024 * 1024;

LOG(Media, "MediaSessionManageriOS::resetRestrictions");

MediaSessionManager::resetRestrictions();
@@ -135,14 +138,19 @@ - (void)stopMonitoringAirPlayRoutes;
if (deviceClass == wkDeviceClassiPhone || deviceClass == wkDeviceClassiPod)
addRestriction(MediaSession::Video, InlineVideoPlaybackRestricted);

if (systemTotalMemory() < systemMemoryRequiredForVideoInBackgroundTabs) {
LOG(Media, "MediaSessionManageriOS::resetRestrictions - restricting video in background tabs because system memory = %zul", systemTotalMemory());
addRestriction(MediaSession::Video, BackgroundTabPlaybackRestricted);
}

addRestriction(MediaSession::Video, ConcurrentPlaybackNotPermitted);
addRestriction(MediaSession::Video, BackgroundPlaybackNotPermitted);
addRestriction(MediaSession::Video, BackgroundProcessPlaybackRestricted);

removeRestriction(MediaSession::Audio, ConcurrentPlaybackNotPermitted);
removeRestriction(MediaSession::Audio, BackgroundPlaybackNotPermitted);
removeRestriction(MediaSession::Audio, BackgroundProcessPlaybackRestricted);

removeRestriction(MediaSession::WebAudio, ConcurrentPlaybackNotPermitted);
removeRestriction(MediaSession::WebAudio, BackgroundPlaybackNotPermitted);
removeRestriction(MediaSession::WebAudio, BackgroundProcessPlaybackRestricted);

removeRestriction(MediaSession::Audio, MetadataPreloadingNotPermitted);
removeRestriction(MediaSession::Video, MetadataPreloadingNotPermitted);
@@ -2403,8 +2403,10 @@ void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const
restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
if (equalIgnoringCase(restrictionsString, "BackgroundPlaybackNotPermitted"))
restrictions += MediaSessionManager::BackgroundPlaybackNotPermitted;
if (equalIgnoringCase(restrictionsString, "BackgroundProcessPlaybackRestricted"))
restrictions += MediaSessionManager::BackgroundProcessPlaybackRestricted;
if (equalIgnoringCase(restrictionsString, "BackgroundTabPlaybackRestricted"))
restrictions += MediaSessionManager::BackgroundTabPlaybackRestricted;

MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
}

0 comments on commit 1f613e9

Please sign in to comment.