diff options
Diffstat (limited to 'Source/WebCore/html/MediaController.cpp')
-rw-r--r-- | Source/WebCore/html/MediaController.cpp | 192 |
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(); |