Skip to content
Permalink
Browse files
2010-03-08 Darin Adler <darin@apple.com>
        Reviewed by Jon Honeycutt.

        Don't auto-play <audio> and <video> elements loaded in background tabs
        https://bugs.webkit.org/show_bug.cgi?id=35886
        rdar://problem/7117745

        * manual-tests/video-in-non-frontmost-tab.html: Added.
        * manual-tests/resources/video-tab.html: Added.

        * html/HTMLMediaElement.h: Added MediaCanStartListener as a base class, and
        added the mediaCanStart function as well as a boolean,
        m_isWaitingUntilMediaCanStart.

        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize
        m_isWaitingUntilMediaCanStart.
        (WebCore::HTMLMediaElement::~HTMLMediaElement): Call
        removeMediaCanStartListener if m_isWaitingUntilMediaCanStart is true.
        (WebCore::HTMLMediaElement::loadInternal): Set m_isWaitingUntilMediaCanStart
        and call addMediaCanStartListener if canStartMedia is false.
        (WebCore::HTMLMediaElement::mediaCanStart): Clear m_isWaitingUntilMediaCanStart
        and call loadInternal.


Canonical link: https://commits.webkit.org/46996@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@55699 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
darinadler committed Mar 9, 2010
1 parent 952d69e commit 6e63f7bcab8192fd49580c7e6308c57bce7a171f
Showing 6 changed files with 62 additions and 7 deletions.
@@ -1,3 +1,28 @@
2010-03-08 Darin Adler <darin@apple.com>

Reviewed by Jon Honeycutt.

Don't auto-play <audio> and <video> elements loaded in background tabs
https://bugs.webkit.org/show_bug.cgi?id=35886
rdar://problem/7117745

* manual-tests/video-in-non-frontmost-tab.html: Added.
* manual-tests/resources/video-tab.html: Added.

* html/HTMLMediaElement.h: Added MediaCanStartListener as a base class, and
added the mediaCanStart function as well as a boolean,
m_isWaitingUntilMediaCanStart.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Initialize
m_isWaitingUntilMediaCanStart.
(WebCore::HTMLMediaElement::~HTMLMediaElement): Call
removeMediaCanStartListener if m_isWaitingUntilMediaCanStart is true.
(WebCore::HTMLMediaElement::loadInternal): Set m_isWaitingUntilMediaCanStart
and call addMediaCanStartListener if canStartMedia is false.
(WebCore::HTMLMediaElement::mediaCanStart): Clear m_isWaitingUntilMediaCanStart
and call loadInternal.

2010-03-08 Csaba Osztrogonác <ossy@webkit.org>

[GTK] Unreviewed buildfix after r55688.
@@ -105,6 +105,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_preload(MediaPlayer::Auto)
, m_playing(false)
, m_processingMediaPlayerCallback(0)
, m_isWaitingUntilMediaCanStart(false)
, m_processingLoad(false)
, m_delayingTheLoadEvent(false)
, m_haveFiredLoadedData(false)
@@ -129,6 +130,11 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)

HTMLMediaElement::~HTMLMediaElement()
{
if (m_isWaitingUntilMediaCanStart) {
if (Page* page = document()->page())
page->removeMediaCanStartListener(this);
}

document()->unregisterForDocumentActivationCallbacks(this);
document()->unregisterForMediaVolumeCallbacks(this);
}
@@ -464,6 +470,16 @@ void HTMLMediaElement::prepareForLoad()

void HTMLMediaElement::loadInternal()
{
// If we can't start a load right away, start it later.
Page* page = document()->page();
if (page && !page->canStartMedia()) {
if (m_isWaitingUntilMediaCanStart)
return;
page->addMediaCanStartListener(this);
m_isWaitingUntilMediaCanStart = true;
return;
}

// If the load() method for this element is already being invoked, then abort these steps.
if (m_processingLoad)
return;
@@ -1960,6 +1976,13 @@ bool HTMLMediaElement::webkitHasClosedCaptions() const
return hasClosedCaptions();
}

void HTMLMediaElement::mediaCanStart()
{
ASSERT(m_isWaitingUntilMediaCanStart);
m_isWaitingUntilMediaCanStart = false;
loadInternal();
}

}

#endif
@@ -29,6 +29,7 @@
#if ENABLE(VIDEO)

#include "HTMLElement.h"
#include "MediaCanStartListener.h"
#include "MediaPlayer.h"

namespace WebCore {
@@ -43,7 +44,7 @@ class TimeRanges;
// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.

class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener {
public:
MediaPlayer* player() const { return m_player.get(); }

@@ -262,6 +263,8 @@ class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
// Pauses playback without changing any states or generating events
void setPausedInternal(bool);

virtual void mediaCanStart();

// Restrictions to change default behaviors. This is effectively a compile time choice at the moment
// because there are no accessor functions.
enum BehaviorRestrictions {
@@ -315,6 +318,8 @@ class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
// calling the media engine recursively.
int m_processingMediaPlayerCallback;

bool m_isWaitingUntilMediaCanStart;

bool m_processingLoad : 1;
bool m_delayingTheLoadEvent : 1;
bool m_haveFiredLoadedData : 1;
@@ -0,0 +1 @@
<video src="http://movies.apple.com/movies/us/apple/ipoditunes/2007/touch/ads/apple_ipodtouch_touch_r640-9cie.mov" controls autoplay>
@@ -0,0 +1,4 @@
This tests that video does not play if it's not in the frontmost tab.
Command-Click <a href="resources/video-tab.html">this link</a> to open it in a non-frontmost tab.
If you hear music before switching tabs, then the test failed.
If not, click on the tab and the video should then play.
@@ -975,8 +975,6 @@ - (void)_closeWithFastTeardown
WTF::RefCountedLeakCounter::suppressMessages("At least one WebView was closed with fast teardown.");
#endif

_private->closed = YES;

[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self];

@@ -1009,6 +1007,8 @@ - (void)_close
if (!_private || _private->closed)
return;

_private->closed = YES;

[self _closingEventHandling];

#ifndef NDEBUG
@@ -1042,9 +1042,6 @@ - (void)_close

[_private->inspector webViewClosed];

// setHostWindow:nil must be called before this value is set (see 5408186)
_private->closed = YES;

// To avoid leaks, call removeDragCaret in case it wasn't called after moveDragCaretToPoint.
[self removeDragCaret];

@@ -3339,7 +3336,7 @@ - (NSString *)userAgentForURL:(NSURL *)url

- (void)setHostWindow:(NSWindow *)hostWindow
{
if (_private->closed)
if (_private->closed && hostWindow)
return;
if (hostWindow == _private->hostWindow)
return;

0 comments on commit 6e63f7b

Please sign in to comment.