Home | History | Annotate | Download | only in track
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef TrackListBase_h
      6 #define TrackListBase_h
      7 
      8 #include "core/events/EventTarget.h"
      9 
     10 #include "core/html/HTMLMediaElement.h"
     11 #include "core/html/track/TrackEvent.h"
     12 
     13 namespace WebCore {
     14 
     15 template<class T>
     16 class TrackListBase : public RefCountedWillBeRefCountedGarbageCollected<TrackListBase<T> >, public EventTargetWithInlineData {
     17     REFCOUNTED_EVENT_TARGET(TrackListBase);
     18     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TrackListBase);
     19 public:
     20     explicit TrackListBase(HTMLMediaElement* mediaElement)
     21         : m_mediaElement(mediaElement)
     22     {
     23     }
     24 
     25     virtual ~TrackListBase()
     26     {
     27 #if !ENABLE(OILPAN)
     28         ASSERT(m_tracks.isEmpty());
     29         ASSERT(!m_mediaElement);
     30 #endif
     31     }
     32 
     33     unsigned length() const { return m_tracks.size(); }
     34     T* anonymousIndexedGetter(unsigned index) const
     35     {
     36         if (index >= m_tracks.size())
     37             return 0;
     38         return m_tracks[index].get();
     39     }
     40 
     41     T* getTrackById(const String& id) const
     42     {
     43         for (unsigned i = 0; i < m_tracks.size(); ++i) {
     44             if (m_tracks[i]->id() == id)
     45                 return m_tracks[i].get();
     46         }
     47 
     48         return 0;
     49     }
     50 
     51     DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
     52     DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
     53     DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
     54 
     55     // EventTarget interface
     56     virtual ExecutionContext* executionContext() const OVERRIDE
     57     {
     58         if (m_mediaElement)
     59             return m_mediaElement->executionContext();
     60         return 0;
     61     }
     62 
     63 #if !ENABLE(OILPAN)
     64     void shutdown()
     65     {
     66         removeAll();
     67         m_mediaElement = nullptr;
     68     }
     69 #endif
     70 
     71     void add(PassRefPtrWillBeRawPtr<T> prpTrack)
     72     {
     73         RefPtrWillBeRawPtr<T> track = prpTrack;
     74 
     75         track->setMediaElement(m_mediaElement);
     76         m_tracks.append(track);
     77         scheduleTrackEvent(EventTypeNames::addtrack, track.release());
     78     }
     79 
     80     void remove(blink::WebMediaPlayer::TrackId trackId)
     81     {
     82         for (unsigned i = 0; i < m_tracks.size(); ++i) {
     83             if (m_tracks[i]->trackId() != trackId)
     84                 continue;
     85 
     86             m_tracks[i]->setMediaElement(0);
     87             scheduleTrackEvent(EventTypeNames::removetrack, m_tracks[i]);
     88             m_tracks.remove(i);
     89             return;
     90         }
     91         ASSERT_NOT_REACHED();
     92     }
     93 
     94     void removeAll()
     95     {
     96         for (unsigned i = 0; i < m_tracks.size(); ++i)
     97             m_tracks[i]->setMediaElement(0);
     98 
     99         m_tracks.clear();
    100     }
    101 
    102     void scheduleChangeEvent()
    103     {
    104         EventInit initializer;
    105         initializer.bubbles = false;
    106         initializer.cancelable = false;
    107         RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::change, initializer);
    108         event->setTarget(this);
    109         m_mediaElement->scheduleEvent(event);
    110     }
    111 
    112     Node* owner() const { return m_mediaElement; }
    113 
    114     void trace(Visitor* visitor)
    115     {
    116         visitor->trace(m_tracks);
    117         visitor->trace(m_mediaElement);
    118         EventTargetWithInlineData::trace(visitor);
    119     }
    120 
    121 private:
    122     void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<T> track)
    123     {
    124         TrackEventInit initializer;
    125         initializer.track = track;
    126         initializer.bubbles = false;
    127         initializer.cancelable = false;
    128         RefPtrWillBeRawPtr<Event> event = TrackEvent::create(eventName, initializer);
    129         event->setTarget(this);
    130         m_mediaElement->scheduleEvent(event);
    131     }
    132 
    133     WillBeHeapVector<RefPtrWillBeMember<T> > m_tracks;
    134     RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
    135 };
    136 
    137 }
    138 
    139 #endif
    140