summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/MediaController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/MediaController.cpp')
-rw-r--r--Source/WebCore/html/MediaController.cpp192
1 files changed, 101 insertions, 91 deletions
diff --git a/Source/WebCore/html/MediaController.cpp b/Source/WebCore/html/MediaController.cpp
index eb7498c5e..25763ad35 100644
--- a/Source/WebCore/html/MediaController.cpp
+++ b/Source/WebCore/html/MediaController.cpp
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* 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
@@ -29,6 +29,8 @@
#include "MediaController.h"
#include "Clock.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
#include "HTMLMediaElement.h"
#include "TimeRanges.h"
#include <wtf/CurrentTime.h>
@@ -37,9 +39,9 @@
using namespace WebCore;
-PassRefPtr<MediaController> MediaController::create(ScriptExecutionContext& context)
+Ref<MediaController> MediaController::create(ScriptExecutionContext& context)
{
- return adoptRef(new MediaController(context));
+ return adoptRef(*new MediaController(context));
}
MediaController::MediaController(ScriptExecutionContext& context)
@@ -50,12 +52,12 @@ MediaController::MediaController(ScriptExecutionContext& context)
, m_muted(false)
, m_readyState(HAVE_NOTHING)
, m_playbackState(WAITING)
- , m_asyncEventTimer(this, &MediaController::asyncEventTimerFired)
- , m_clearPositionTimer(this, &MediaController::clearPositionTimerFired)
+ , m_asyncEventTimer(*this, &MediaController::asyncEventTimerFired)
+ , m_clearPositionTimer(*this, &MediaController::clearPositionTimerFired)
, m_closedCaptionsVisible(false)
, m_clock(Clock::create())
, m_scriptExecutionContext(context)
- , m_timeupdateTimer(this, &MediaController::timeupdateTimerFired)
+ , m_timeupdateTimer(*this, &MediaController::scheduleTimeupdateEvent)
, m_previousTimeupdateTime(0)
{
}
@@ -64,28 +66,26 @@ MediaController::~MediaController()
{
}
-void MediaController::addMediaElement(HTMLMediaElement* element)
+void MediaController::addMediaElement(HTMLMediaElement& element)
{
- ASSERT(element);
- ASSERT(!m_mediaElements.contains(element));
+ ASSERT(!m_mediaElements.contains(&element));
- m_mediaElements.append(element);
+ m_mediaElements.append(&element);
bringElementUpToSpeed(element);
}
-void MediaController::removeMediaElement(HTMLMediaElement* element)
+void MediaController::removeMediaElement(HTMLMediaElement& element)
{
- ASSERT(element);
- ASSERT(m_mediaElements.contains(element));
- m_mediaElements.remove(m_mediaElements.find(element));
+ ASSERT(m_mediaElements.contains(&element));
+ m_mediaElements.remove(m_mediaElements.find(&element));
}
-bool MediaController::containsMediaElement(HTMLMediaElement* element) const
+bool MediaController::containsMediaElement(HTMLMediaElement& element) const
{
- return m_mediaElements.contains(element);
+ return m_mediaElements.contains(&element);
}
-PassRefPtr<TimeRanges> MediaController::buffered() const
+Ref<TimeRanges> MediaController::buffered() const
{
if (m_mediaElements.isEmpty())
return TimeRanges::create();
@@ -93,13 +93,13 @@ PassRefPtr<TimeRanges> MediaController::buffered() const
// The buffered attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent has buffered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
+ Ref<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get());
+ bufferedRanges->intersectWith(m_mediaElements[index]->buffered());
return bufferedRanges;
}
-PassRefPtr<TimeRanges> MediaController::seekable() const
+Ref<TimeRanges> MediaController::seekable() const
{
if (m_mediaElements.isEmpty())
return TimeRanges::create();
@@ -107,13 +107,13 @@ PassRefPtr<TimeRanges> MediaController::seekable() const
// The seekable attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent is able to seek to, at the time the attribute is evaluated.
- RefPtr<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
+ Ref<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- seekableRanges->intersectWith(m_mediaElements[index]->seekable().get());
+ seekableRanges->intersectWith(m_mediaElements[index]->seekable());
return seekableRanges;
}
-PassRefPtr<TimeRanges> MediaController::played()
+Ref<TimeRanges> MediaController::played()
{
if (m_mediaElements.isEmpty())
return TimeRanges::create();
@@ -121,9 +121,9 @@ PassRefPtr<TimeRanges> MediaController::played()
// The played attribute must return a new static normalized TimeRanges object that represents
// the union of the ranges of the media resources of the slaved media elements that the
// user agent has so far rendered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> playedRanges = m_mediaElements.first()->played();
+ Ref<TimeRanges> playedRanges = m_mediaElements.first()->played();
for (size_t index = 1; index < m_mediaElements.size(); ++index)
- playedRanges->unionWith(m_mediaElements[index]->played().get());
+ playedRanges->unionWith(m_mediaElements[index]->played());
return playedRanges;
}
@@ -132,8 +132,8 @@ double MediaController::duration() const
// FIXME: Investigate caching the maximum duration and only updating the cached value
// when the slaved media elements' durations change.
double maxDuration = 0;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- double duration = m_mediaElements[index]->duration();
+ for (auto& mediaElement : m_mediaElements) {
+ double duration = mediaElement->duration();
if (std::isnan(duration))
continue;
maxDuration = std::max(maxDuration, duration);
@@ -170,10 +170,11 @@ void MediaController::setCurrentTime(double time)
m_clock->setCurrentTime(time);
// Seek each slaved media element to the new playback position relative to the media element timeline.
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->seek(time);
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->seek(MediaTime::createWithDouble(time));
scheduleTimeupdateEvent();
+ m_resetCurrentTimeInNextPlay = false;
}
void MediaController::unpause()
@@ -193,8 +194,8 @@ void MediaController::play()
{
// When the play() method is invoked, the user agent must invoke the play method of each
// slaved media element in turn,
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->play();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->play();
// and then invoke the unpause method of the MediaController.
unpause();
@@ -241,25 +242,23 @@ void MediaController::setPlaybackRate(double rate)
// playback rate to the new value,
m_clock->setPlayRate(rate);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlaybackRate();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->updatePlaybackRate();
// then queue a task to fire a simple event named ratechange at the MediaController.
scheduleEvent(eventNames().ratechangeEvent);
}
-void MediaController::setVolume(double level, ExceptionCode& code)
+ExceptionOr<void> MediaController::setVolume(double level)
{
if (m_volume == level)
- return;
+ return { };
// If the new value is outside the range 0.0 to 1.0 inclusive, then, on setting, an
// IndexSizeError exception must be raised instead.
- if (level < 0 || level > 1) {
- code = INDEX_SIZE_ERR;
- return;
- }
-
+ if (!(level >= 0 && level <= 1))
+ return Exception { INDEX_SIZE_ERR };
+
// The volume attribute, on setting, if the new value is in the range 0.0 to 1.0 inclusive,
// must set the MediaController's media controller volume multiplier to the new value
m_volume = level;
@@ -267,8 +266,10 @@ void MediaController::setVolume(double level, ExceptionCode& code)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(eventNames().volumechangeEvent);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->updateVolume();
+
+ return { };
}
void MediaController::setMuted(bool flag)
@@ -283,25 +284,25 @@ void MediaController::setMuted(bool flag)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(eventNames().volumechangeEvent);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->updateVolume();
}
static const AtomicString& playbackStateWaiting()
{
- DEFINE_STATIC_LOCAL(AtomicString, waiting, ("waiting", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<AtomicString> waiting("waiting", AtomicString::ConstructFromLiteral);
return waiting;
}
static const AtomicString& playbackStatePlaying()
{
- DEFINE_STATIC_LOCAL(AtomicString, playing, ("playing", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<AtomicString> playing("playing", AtomicString::ConstructFromLiteral);
return playing;
}
static const AtomicString& playbackStateEnded()
{
- DEFINE_STATIC_LOCAL(AtomicString, ended, ("ended", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<AtomicString> ended("ended", AtomicString::ConstructFromLiteral);
return ended;
}
@@ -445,10 +446,15 @@ void MediaController::updatePlaybackState()
break;
case ENDED:
eventName = eventNames().endedEvent;
+ m_resetCurrentTimeInNextPlay = true;
m_clock->stop();
m_timeupdateTimer.stop();
break;
case PLAYING:
+ if (m_resetCurrentTimeInNextPlay) {
+ m_resetCurrentTimeInNextPlay = false;
+ m_clock->setCurrentTime(0);
+ }
eventName = eventNames().playingEvent;
m_clock->start();
startTimeupdateTimer();
@@ -466,19 +472,18 @@ void MediaController::updatePlaybackState()
void MediaController::updateMediaElements()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlayState();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->updatePlayState();
}
-void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
+void MediaController::bringElementUpToSpeed(HTMLMediaElement& element)
{
- ASSERT(element);
- ASSERT(m_mediaElements.contains(element));
+ ASSERT(m_mediaElements.contains(&element));
// When the user agent is to bring a media element up to speed with its new media controller,
// it must seek that media element to the MediaController's media controller position relative
// to the media element's timeline.
- element->seek(currentTime());
+ element.seekInternal(MediaTime::createWithDouble(currentTime()));
}
bool MediaController::isBlocked() const
@@ -492,8 +497,7 @@ bool MediaController::isBlocked() const
return false;
bool allPaused = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- HTMLMediaElement* element = m_mediaElements[index];
+ for (auto& element : m_mediaElements) {
// or if any of its slaved media elements are blocked media elements,
if (element->isBlocked())
return true;
@@ -523,8 +527,8 @@ bool MediaController::hasEnded() const
return false;
bool allHaveEnded = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->ended())
+ for (auto& mediaElement : m_mediaElements) {
+ if (!mediaElement->ended())
allHaveEnded = false;
}
return allHaveEnded;
@@ -537,25 +541,24 @@ void MediaController::scheduleEvent(const AtomicString& eventName)
m_asyncEventTimer.startOneShot(0);
}
-void MediaController::asyncEventTimerFired(Timer<MediaController>&)
+void MediaController::asyncEventTimerFired()
{
- Vector<RefPtr<Event>> pendingEvents;
+ Vector<Ref<Event>> pendingEvents;
m_pendingEvents.swap(pendingEvents);
- size_t count = pendingEvents.size();
- for (size_t index = 0; index < count; ++index)
- dispatchEvent(pendingEvents[index].release(), IGNORE_EXCEPTION);
+ for (auto& pendingEvent : pendingEvents)
+ dispatchEvent(pendingEvent);
}
-void MediaController::clearPositionTimerFired(Timer<MediaController>&)
+void MediaController::clearPositionTimerFired()
{
m_position = MediaPlayer::invalidTime();
}
bool MediaController::hasAudio() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasAudio())
+ for (auto& mediaElement : m_mediaElements) {
+ if (mediaElement->hasAudio())
return true;
}
return false;
@@ -563,8 +566,8 @@ bool MediaController::hasAudio() const
bool MediaController::hasVideo() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasVideo())
+ for (auto& mediaElement : m_mediaElements) {
+ if (mediaElement->hasVideo())
return true;
}
return false;
@@ -572,8 +575,8 @@ bool MediaController::hasVideo() const
bool MediaController::hasClosedCaptions() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasClosedCaptions())
+ for (auto& mediaElement : m_mediaElements) {
+ if (mediaElement->hasClosedCaptions())
return true;
}
return false;
@@ -582,14 +585,14 @@ bool MediaController::hasClosedCaptions() const
void MediaController::setClosedCaptionsVisible(bool visible)
{
m_closedCaptionsVisible = visible;
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->setClosedCaptionsVisible(visible);
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->setClosedCaptionsVisible(visible);
}
bool MediaController::supportsScanning() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->supportsScanning())
+ for (auto& mediaElement : m_mediaElements) {
+ if (!mediaElement->supportsScanning())
return false;
}
return true;
@@ -597,27 +600,39 @@ bool MediaController::supportsScanning() const
void MediaController::beginScrubbing()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->beginScrubbing();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->beginScrubbing();
if (m_playbackState == PLAYING)
m_clock->stop();
}
void MediaController::endScrubbing()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->endScrubbing();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->endScrubbing();
if (m_playbackState == PLAYING)
m_clock->start();
}
+void MediaController::beginScanning(ScanDirection direction)
+{
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->beginScanning(direction);
+}
+
+void MediaController::endScanning()
+{
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->endScanning();
+}
+
bool MediaController::canPlay() const
{
if (m_paused)
return true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->canPlay())
+ for (auto& mediaElement : m_mediaElements) {
+ if (!mediaElement->canPlay())
return false;
}
return true;
@@ -625,8 +640,8 @@ bool MediaController::canPlay() const
bool MediaController::isLiveStream() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->isLiveStream())
+ for (auto& mediaElement : m_mediaElements) {
+ if (!mediaElement->isLiveStream())
return false;
}
return true;
@@ -634,8 +649,8 @@ bool MediaController::isLiveStream() const
bool MediaController::hasCurrentSrc() const
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->hasCurrentSrc())
+ for (auto& mediaElement : m_mediaElements) {
+ if (!mediaElement->hasCurrentSrc())
return false;
}
return true;
@@ -643,8 +658,8 @@ bool MediaController::hasCurrentSrc() const
void MediaController::returnToRealtime()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->returnToRealtime();
+ for (auto& mediaElement : m_mediaElements)
+ mediaElement->returnToRealtime();
}
// The spec says to fire periodic timeupdate events (those sent while playing) every
@@ -659,11 +674,6 @@ void MediaController::startTimeupdateTimer()
m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency);
}
-void MediaController::timeupdateTimerFired(Timer<MediaController>&)
-{
- scheduleTimeupdateEvent();
-}
-
void MediaController::scheduleTimeupdateEvent()
{
double now = monotonicallyIncreasingTime();