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 blink {
     14 
     15 template<class T>
     16 class TrackListBase : public RefCountedWillBeGarbageCollectedFinalized<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         RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::change);
    105         event->setTarget(this);
    106         m_mediaElement->scheduleEvent(event);
    107     }
    108 
    109     Node* owner() const { return m_mediaElement; }
    110 
    111     void trace(Visitor* visitor)
    112     {
    113         visitor->trace(m_tracks);
    114         visitor->trace(m_mediaElement);
    115         EventTargetWithInlineData::trace(visitor);
    116     }
    117 
    118 private:
    119     void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<T> track)
    120     {
    121         TrackEventInit initializer;
    122         initializer.track = track;
    123         initializer.bubbles = false;
    124         initializer.cancelable = false;
    125         RefPtrWillBeRawPtr<Event> event = TrackEvent::create(eventName, initializer);
    126         event->setTarget(this);
    127         m_mediaElement->scheduleEvent(event);
    128     }
    129 
    130     WillBeHeapVector<RefPtrWillBeMember<T> > m_tracks;
    131     RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
    132 };
    133 
    134 }
    135 
    136 #endif
    137