Allow MediaSessionManager to restrict 'preload' behavior

https://bugs.webkit.org/show_bug.cgi?id=127297

Reviewed by Jer Noble.

Source/WebCore: 

Tests: media/video-restricted-no-preload-auto.html
       media/video-restricted-no-preload-metadata.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::parseAttribute): Apply restrictions to preload attribute before
    passing to media engine.
(WebCore::HTMLMediaElement::loadResource): Ditto.

* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::effectivePreloadForElement): New, limit preload according to restrictions.
* html/HTMLMediaSession.h:

* platform/audio/MediaSessionManager.h:
* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::resetRestrictions): Limit preload to metadata only. Drive-by
    static deviceClass initialization cleanup.

* testing/Internals.cpp:
(WebCore::Internals::setMediaSessionRestrictions): Support MetadataPreloadingNotPermitted and
    AutoPreloadingNotPermitted.

LayoutTests: 

* media/video-restricted-no-preload-auto-expected.txt: Added.
* media/video-restricted-no-preload-auto.html: Added.
* media/video-restricted-no-preload-metadata-expected.txt: Added.
* media/video-restricted-no-preload-metadata.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162360 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5169263b
2014-01-20 Eric Carlson <eric.carlson@apple.com>
Allow MediaSessionManager to restrict 'preload' behavior
https://bugs.webkit.org/show_bug.cgi?id=127297
Reviewed by Jer Noble.
* media/video-restricted-no-preload-auto-expected.txt: Added.
* media/video-restricted-no-preload-auto.html: Added.
* media/video-restricted-no-preload-metadata-expected.txt: Added.
* media/video-restricted-no-preload-metadata.html: Added.
2014-01-20 Mihai Tica <mitica@adobe.com>
Fix test expectations for css3/compositing/background-blend-mode-data-uri-svg-image.html
Test that "no auto-loading restriction" only allows metadata to load in spite of preload='auto'.
** setting video.src
EXPECTED (video.preload == 'auto') OK
RUN(internals.setMediaSessionRestrictions('video', 'AutoPreloadingNotPermitted'))
EVENT(loadedmetadata)
EXPECTED (video.readyState < '2') OK
** Pausing...
** 250ms timer fired
EXPECTED (video.readyState < '2') OK
EXPECTED (video.buffered.length == '0') OK
RUN(video.play())
EVENT(canplaythrough)
END OF TEST
<html>
<head>
<script src="media-file.js"></script>
<script src="video-test.js"></script>
<script>
var playCalled = false;
function canplaythrough()
{
consoleWrite("");
if (!playCalled)
consoleWrite("*** FAIL: media data loaded before play() was called ***<br>");
endTest();
}
function play()
{
consoleWrite("** 250ms timer fired");
testExpected("video.readyState", HTMLMediaElement.HAVE_CURRENT_DATA, "<");
testExpected("video.buffered.length", 0, "==");
playCalled = true;
run("video.play()");
consoleWrite("");
}
function loadedmetadata()
{
testExpected("video.readyState", HTMLMediaElement.HAVE_CURRENT_DATA, "<");
// Wait 250ms before play()ing to make sure setting src did not kick off the load.
consoleWrite("** Pausing...<br>");
setTimeout(play, 250);
consoleWrite("");
}
function start()
{
if (!window.internals) {
failTest('This test requires window.internals.');
return;
}
findMediaElement();
consoleWrite("** setting video.src");
video.src = findMediaFile("video", "content/test");
testExpected("video.preload", "auto");
waitForEvent('loadedmetadata', loadedmetadata);
waitForEvent('canplaythrough', canplaythrough);
failTestIn(2000);
run("internals.setMediaSessionRestrictions('video', 'AutoPreloadingNotPermitted')");
consoleWrite("");
}
</script>
</head>
<body onload="start()">
<video controls preload=auto></video>
<p>Test that "no auto-loading restriction" only allows metadata to load in spite of preload='auto'.</p>
</body>
</html>
Test that "no preloading restriction" disables preloading in spite of preload='auto'.
** setting video.src
EXPECTED (video.preload == 'auto') OK
RUN(internals.setMediaSessionRestrictions('video', 'MetadataPreloadingNotPermitted'))
** Pausing...
** 250ms timer fired
EXPECTED (video.readyState == '0') OK
EXPECTED (video.buffered.length == '0') OK
RUN(video.load())
EVENT(loadedmetadata)
END OF TEST
<html>
<head>
<script src="media-file.js"></script>
<script src="video-test.js"></script>
<script>
var loadCalled = false;
function loadedmetadata()
{
consoleWrite("");
if (!loadCalled)
consoleWrite("*** FAIL: media data loaded before load() was called ***<br>");
endTest();
}
function load()
{
consoleWrite("** 250ms timer fired");
testExpected("video.readyState", HTMLMediaElement.HAVE_NOTHING);
testExpected("video.buffered.length", 0, "==");
loadCalled = true;
run("video.load()");
consoleWrite("");
}
function start()
{
if (!window.internals) {
failTest('This test requires window.internals.');
return;
}
findMediaElement();
consoleWrite("** setting video.src");
video.src = findMediaFile("video", "content/test");
testExpected("video.preload", "auto");
waitForEvent('loadedmetadata', loadedmetadata);
run("internals.setMediaSessionRestrictions('video', 'MetadataPreloadingNotPermitted')");
// Wait 250ms before load()ing to make sure setting src did not kick off the load.
consoleWrite("** Pausing...<br>");
setTimeout(load, 250);
failTestIn(2000);
}
</script>
</head>
<body onload="start()">
<video controls preload=auto></video>
<p>Test that "no preloading restriction" disables preloading in spite of preload='auto'.</p>
</body>
</html>
2014-01-20 Eric Carlson <eric.carlson@apple.com>
Allow MediaSessionManager to restrict 'preload' behavior
https://bugs.webkit.org/show_bug.cgi?id=127297
Reviewed by Jer Noble.
Tests: media/video-restricted-no-preload-auto.html
media/video-restricted-no-preload-metadata.html
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::parseAttribute): Apply restrictions to preload attribute before
passing to media engine.
(WebCore::HTMLMediaElement::loadResource): Ditto.
* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::effectivePreloadForElement): New, limit preload according to restrictions.
* html/HTMLMediaSession.h:
* platform/audio/MediaSessionManager.h:
* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::resetRestrictions): Limit preload to metadata only. Drive-by
static deviceClass initialization cleanup.
* testing/Internals.cpp:
(WebCore::Internals::setMediaSessionRestrictions): Support MetadataPreloadingNotPermitted and
AutoPreloadingNotPermitted.
2014-01-20 Andreas Kling <akling@apple.com>
Let RenderImage construct its RenderImageResource.
......@@ -546,7 +546,7 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
// The attribute must be ignored if the autoplay attribute is present
if (!autoplay() && m_player)
m_player->setPreload(m_preload);
m_player->setPreload(m_mediaSession->effectivePreloadForElement(*this));
} else if (name == mediagroupAttr)
setMediaGroup(value);
......@@ -987,12 +987,13 @@ void HTMLMediaElement::prepareForLoad()
// The spec doesn't say to block the load event until we actually run the asynchronous section
// algorithm, but do it now because we won't start that until after the timer fires and the
// event may have already fired by then.
if (m_preload != MediaPlayer::None)
MediaPlayer::Preload effectivePreload = m_mediaSession->effectivePreloadForElement(*this);
if (effectivePreload != MediaPlayer::None)
setShouldDelayLoadEvent(true);
#if PLATFORM(IOS)
Settings* settings = document().settings();
if (m_preload != MediaPlayer::None && settings && settings->mediaDataLoadsAutomatically())
if (effectivePreload != MediaPlayer::None && settings && settings->mediaDataLoadsAutomatically())
prepareToPlay();
#endif
......@@ -1211,7 +1212,7 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT
setDisplayMode(Unknown);
if (!autoplay())
m_player->setPreload(m_preload);
m_player->setPreload(m_mediaSession->effectivePreloadForElement(*this));
m_player->setPreservesPitch(m_webkitPreservesPitch);
if (fastHasAttribute(mutedAttr))
......
......@@ -424,6 +424,8 @@ public:
RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
#endif
MediaPlayer::Preload preloadValue() const { return m_preload; }
protected:
HTMLMediaElement(const QualifiedName&, Document&, bool);
virtual ~HTMLMediaElement();
......
......@@ -143,6 +143,22 @@ bool HTMLMediaSession::showingPlaybackTargetPickerPermitted(const HTMLMediaEleme
}
#endif
MediaPlayer::Preload HTMLMediaSession::effectivePreloadForElement(const HTMLMediaElement& element) const
{
MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType());
MediaPlayer::Preload preload = element.preloadValue();
if ((restrictions & MediaSessionManager::MetadataPreloadingNotPermitted) == MediaSessionManager::MetadataPreloadingNotPermitted)
return MediaPlayer::None;
if ((restrictions & MediaSessionManager::AutoPreloadingNotPermitted) == MediaSessionManager::AutoPreloadingNotPermitted) {
if (preload > MediaPlayer::MetaData)
return MediaPlayer::MetaData;
}
return preload;
}
void HTMLMediaSession::clientWillBeginPlayback() const
{
MediaSessionManager::sharedManager().sessionWillBeginPlayback(*this);
......
......@@ -28,6 +28,7 @@
#if ENABLE(VIDEO)
#include "MediaPlayer.h"
#include "MediaSession.h"
namespace WebCore {
......@@ -52,6 +53,7 @@ public:
bool showingPlaybackTargetPickerPermitted(const HTMLMediaElement&) const;
#endif
bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&) const;
// Restrictions to modify default behaviors.
enum BehaviorRestrictionFlags {
......
......@@ -50,7 +50,9 @@ public:
enum SessionRestrictionFlags {
NoRestrictions = 0,
ConcurrentPlaybackNotPermitted = 1 << 0,
InlineVideoPlaybackRestricted = 1 << 0,
InlineVideoPlaybackRestricted = 1 << 1,
MetadataPreloadingNotPermitted = 1 << 2,
AutoPreloadingNotPermitted = 1 << 3,
};
typedef unsigned SessionRestrictions;
......
......@@ -79,12 +79,15 @@ void MediaSessionManageriOS::resetRestrictions()
{
MediaSessionManager::resetRestrictions();
DEFINE_STATIC_LOCAL(wkDeviceClass, deviceClass, (iosDeviceClass()));
static wkDeviceClass deviceClass = iosDeviceClass();
if (deviceClass == wkDeviceClassiPhone || deviceClass == wkDeviceClassiPod)
addRestriction(MediaSession::Video, InlineVideoPlaybackRestricted);
addRestriction(MediaSession::Video, ConcurrentPlaybackNotPermitted);
removeRestriction(MediaSession::Audio, MetadataPreloadingNotPermitted);
removeRestriction(MediaSession::Video, MetadataPreloadingNotPermitted);
addRestriction(MediaSession::Audio, AutoPreloadingNotPermitted);
addRestriction(MediaSession::Video, AutoPreloadingNotPermitted);
}
} // namespace WebCore
......
......@@ -2211,7 +2211,11 @@ void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const
restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment