1/* 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#if ENABLE(VIDEO_TRACK) 29 30#include "TrackListBase.h" 31 32#include "EventNames.h" 33#include "HTMLMediaElement.h" 34#include "ScriptExecutionContext.h" 35#include "TrackEvent.h" 36 37using namespace WebCore; 38 39TrackListBase::TrackListBase(HTMLMediaElement* element, ScriptExecutionContext* context) 40 : m_context(context) 41 , m_element(element) 42 , m_asyncEventQueue(*this) 43{ 44 ASSERT(context->isDocument()); 45} 46 47TrackListBase::~TrackListBase() 48{ 49} 50 51Element* TrackListBase::element() const 52{ 53 return m_element; 54} 55 56unsigned TrackListBase::length() const 57{ 58 return m_inbandTracks.size(); 59} 60 61void TrackListBase::remove(TrackBase* track, bool scheduleEvent) 62{ 63 size_t index = m_inbandTracks.find(track); 64 ASSERT(index != notFound); 65 66 ASSERT(track->mediaElement() == m_element); 67 track->setMediaElement(0); 68 69 RefPtr<TrackBase> trackRef = m_inbandTracks[index]; 70 71 m_inbandTracks.remove(index); 72 73 if (scheduleEvent) 74 scheduleRemoveTrackEvent(trackRef.release()); 75} 76 77bool TrackListBase::contains(TrackBase* track) const 78{ 79 return m_inbandTracks.find(track) != notFound; 80} 81 82void TrackListBase::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TrackBase> track) 83{ 84 TrackEventInit initializer; 85 initializer.track = track; 86 initializer.bubbles = false; 87 initializer.cancelable = false; 88 89 m_asyncEventQueue.enqueueEvent(TrackEvent::create(eventName, initializer)); 90} 91 92void TrackListBase::scheduleAddTrackEvent(PassRefPtr<TrackBase> track) 93{ 94 // 4.8.10.5 Loading the media resource 95 // ... 96 // Fire a trusted event with the name addtrack, that does not bubble and is 97 // not cancelable, and that uses the TrackEvent interface, with the track 98 // attribute initialized to the new AudioTrack object, at this 99 // AudioTrackList object. 100 // ... 101 // Fire a trusted event with the name addtrack, that does not bubble and is 102 // not cancelable, and that uses the TrackEvent interface, with the track 103 // attribute initialized to the new VideoTrack object, at this 104 // VideoTrackList object. 105 106 // 4.8.10.12.3 Sourcing out-of-band text tracks 107 // 4.8.10.12.4 Text track API 108 // ... then queue a task to fire an event with the name addtrack, that does not 109 // bubble and is not cancelable, and that uses the TrackEvent interface, with 110 // the track attribute initialized to the text track's TextTrack object, at 111 // the media element's textTracks attribute's TextTrackList object. 112 scheduleTrackEvent(eventNames().addtrackEvent, track); 113} 114 115void TrackListBase::scheduleRemoveTrackEvent(PassRefPtr<TrackBase> track) 116{ 117 // 4.8.10.6 Offsets into the media resource 118 // If at any time the user agent learns that an audio or video track has 119 // ended and all media data relating to that track corresponds to parts of 120 // the media timeline that are before the earliest possible position, the 121 // user agent may queue a task to remove the track from the audioTracks 122 // attribute's AudioTrackList object or the videoTracks attribute's 123 // VideoTrackList object as appropriate and then fire a trusted event 124 // with the name removetrack, that does not bubble and is not cancelable, 125 // and that uses the TrackEvent interface, with the track attribute 126 // initialized to the AudioTrack or VideoTrack object representing the 127 // track, at the media element's aforementioned AudioTrackList or 128 // VideoTrackList object. 129 130 // 4.8.10.12.3 Sourcing out-of-band text tracks 131 // When a track element's parent element changes and the old parent was a 132 // media element, then the user agent must remove the track element's 133 // corresponding text track from the media element's list of text tracks, 134 // and then queue a task to fire a trusted event with the name removetrack, 135 // that does not bubble and is not cancelable, and that uses the TrackEvent 136 // interface, with the track attribute initialized to the text track's 137 // TextTrack object, at the media element's textTracks attribute's 138 // TextTrackList object. 139 scheduleTrackEvent(eventNames().removetrackEvent, track); 140} 141 142void TrackListBase::scheduleChangeEvent() 143{ 144 // 4.8.10.6 Offsets into the media resource 145 // Whenever an audio track in an AudioTrackList is enabled or disabled, the 146 // user agent must queue a task to fire a simple event named change at the 147 // AudioTrackList object. 148 // ... 149 // Whenever a track in a VideoTrackList that was previously not selected is 150 // selected, the user agent must queue a task to fire a simple event named 151 // change at the VideoTrackList object. 152 153 EventInit initializer; 154 initializer.bubbles = false; 155 initializer.cancelable = false; 156 157 m_asyncEventQueue.enqueueEvent(Event::create(eventNames().changeEvent, initializer)); 158} 159 160bool TrackListBase::isAnyTrackEnabled() const 161{ 162 for (size_t i = 0; i < m_inbandTracks.size(); ++i) { 163 TrackBase* track = m_inbandTracks[i].get(); 164 if (track->enabled()) 165 return true; 166 } 167 return false; 168} 169 170#endif 171