Bug 865407 - Part 1: Add TextTrackManager class r=cpearce
authorRick Eyre <rick.eyre@hotmail.com>
Wed, 23 Oct 2013 11:45:00 -0700
changeset 160513 9d7ed37acfe6f2e9797869b3e690cd8f38a01141
parent 160512 dfb15cca5df4504be76e9a8965c7f57b2aeab600
child 160514 d75468812ea4506eee534c5bda18225ffab32530
push idunknown
push userunknown
push dateunknown
reviewerscpearce
bugs865407
milestone27.0a1
Bug 865407 - Part 1: Add TextTrackManager class r=cpearce This class will manage everything to do with TextTracks for the HTMLMediaElement.
content/html/content/public/HTMLMediaElement.h
content/html/content/src/HTMLMediaElement.cpp
content/html/content/src/TextTrackManager.cpp
content/html/content/src/TextTrackManager.h
content/html/content/src/moz.build
--- a/content/html/content/public/HTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -12,17 +12,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsIObserver.h"
 #include "mozilla/CORSMode.h"
 #include "DOMMediaStream.h"
 #include "AudioChannelCommon.h"
 #include "DecoderTraits.h"
 #include "nsIAudioChannelAgent.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/TextTrackList.h"
+#include "mozilla/dom/TextTrackManager.h"
 
 // Define to output information on decoding and painting framerate
 /* #define DEBUG_FRAME_RATE 1 */
 
 class nsIChannel;
 class nsIHttpChannel;
 class nsILoadGroup;
 
@@ -45,16 +45,17 @@ class nsITimer;
 class nsRange;
 class nsIRunnable;
 
 namespace mozilla {
 namespace dom {
 
 class MediaError;
 class MediaSource;
+class TextTrackList;
 
 class HTMLMediaElement : public nsGenericHTMLElement,
                          public nsIObserver,
                          public MediaDecoderOwner,
                          public nsIAudioChannelAgentCallback
 {
 public:
   typedef mozilla::TimeStamp TimeStamp;
@@ -521,22 +522,24 @@ public:
 
   TextTrackList* TextTracks() const;
 
   already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
                                            const nsAString& aLabel,
                                            const nsAString& aLanguage);
 
   void AddTextTrack(TextTrack* aTextTrack) {
-    mTextTracks->AddTextTrack(aTextTrack);
+    if (mTextTrackManager) {
+      mTextTrackManager->AddTextTrack(aTextTrack);
+    }
   }
 
   void RemoveTextTrack(TextTrack* aTextTrack) {
-    if (mTextTracks) {
-      mTextTracks->RemoveTextTrack(*aTextTrack);
+    if (mTextTrackManager) {
+      mTextTrackManager->RemoveTextTrack(aTextTrack);
     }
   }
 
   /**
    * A public wrapper for FinishDecoderSetup()
    */
   nsresult FinishDecoderSetup(MediaDecoder* aDecoder, MediaResource* aStream) {
     return FinishDecoderSetup(aDecoder, aStream, nullptr, nullptr);
@@ -1143,16 +1146,15 @@ protected:
   bool mAudioChannelFaded;
 
   // Is this media element playing?
   bool mPlayingThroughTheAudioChannel;
 
   // An agent used to join audio channel service.
   nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
 
-  // List of our attached text track objects.
-  nsRefPtr<TextTrackList> mTextTracks;
+  nsRefPtr<TextTrackManager> mTextTrackManager;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLMediaElement_h
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -420,17 +420,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceLoadCandidate)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelAgent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTracks);
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
   if (tmp->mSrcStream) {
     // Need to EndMediaStreamPlayback to clear mSrcStream and make sure everything
     // gets unhooked correctly.
     tmp->EndSrcMediaStreamPlayback();
   }
@@ -440,17 +440,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioChannelAgent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlayed);
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTracks);
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 // nsIDOMHTMLMediaElement
@@ -1994,17 +1994,17 @@ HTMLMediaElement::HTMLMediaElement(alrea
   }
 #endif
 
   mPaused.SetOuter(this);
 
   RegisterFreezableElement();
   NotifyOwnerDocumentActivityChanged();
 
-  mTextTracks = new TextTrackList(OwnerDoc()->GetParentObject());
+  mTextTrackManager = new TextTrackManager(this);
 }
 
 HTMLMediaElement::~HTMLMediaElement()
 {
   NS_ASSERTION(!mHasSelfReference,
                "How can we be destroyed if we're still holding a self reference?");
 
   if (mVideoFrameContainer) {
@@ -2974,17 +2974,19 @@ void HTMLMediaElement::SeekStarted()
 
 void HTMLMediaElement::SeekCompleted()
 {
   mPlayingBeforeSeek = false;
   SetPlayedOrSeeked(true);
   DispatchAsyncEvent(NS_LITERAL_STRING("seeked"));
   // We changed whether we're seeking so we need to AddRemoveSelfReference
   AddRemoveSelfReference();
-  mTextTracks->DidSeek();
+  if (mTextTrackManager) {
+    mTextTrackManager->DidSeek();
+  }
 }
 
 void HTMLMediaElement::NotifySuspendedByCache(bool aIsSuspended)
 {
   mDownloadSuspendedByCache = aIsSuspended;
   // If this is an autoplay element, we may need to kick off its autoplaying
   // now so we consume data and hopefully free up cache space.
   CheckAutoplayDataReady();
@@ -3663,21 +3665,21 @@ void HTMLMediaElement::FireTimeUpdate(bo
   if (mFragmentEnd >= 0.0 && time >= mFragmentEnd) {
     Pause();
     mFragmentEnd = -1.0;
     mFragmentStart = -1.0;
     mDecoder->SetFragmentEndTime(mFragmentEnd);
   }
 
   // Update visible text tracks.
-  // Here mTextTracks can be null if the cycle collector has unlinked
+  // Here mTextTrackManager can be null if the cycle collector has unlinked
   // us before our parent. In that case UnbindFromTree will call us
   // when our parent is unlinked.
-  if (mTextTracks) {
-    mTextTracks->Update(time);
+  if (mTextTrackManager) {
+    mTextTrackManager->Update(time);
   }
 }
 
 void HTMLMediaElement::GetCurrentSpec(nsCString& aString)
 {
   if (mLoadingSrc) {
     mLoadingSrc->GetSpec(aString);
   } else {
@@ -3900,21 +3902,23 @@ NS_IMETHODIMP HTMLMediaElement::CanPlayC
   mPaused.SetCanPlay(canPlay != AUDIO_CHANNEL_STATE_MUTED);
   return NS_OK;
 }
 
 /* readonly attribute TextTrackList textTracks; */
 TextTrackList*
 HTMLMediaElement::TextTracks() const
 {
-  return mTextTracks;
+  return mTextTrackManager ? mTextTrackManager->TextTracks() : nullptr;
 }
 
 already_AddRefed<TextTrack>
 HTMLMediaElement::AddTextTrack(TextTrackKind aKind,
                                const nsAString& aLabel,
                                const nsAString& aLanguage)
 {
-  return mTextTracks->AddTextTrack(this, aKind, aLabel, aLanguage);
+  return mTextTrackManager ? mTextTrackManager->AddTextTrack(aKind, aLabel,
+                                                             aLanguage)
+                           : nullptr;
 }
 
 } // namespace dom
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/TextTrackManager.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/TextTrackManager.h"
+#include "mozilla/dom/HTMLMediaElement.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_1(TextTrackManager, mTextTracks)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TextTrackManager, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TextTrackManager, Release)
+
+TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
+  : mMediaElement(aMediaElement)
+{
+  MOZ_COUNT_CTOR(TextTrackManager);
+  mTextTracks = new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject());
+}
+
+TextTrackManager::~TextTrackManager()
+{
+  MOZ_COUNT_DTOR(TextTrackManager);
+}
+
+TextTrackList*
+TextTrackManager::TextTracks() const
+{
+  return mTextTracks;
+}
+
+already_AddRefed<TextTrack>
+TextTrackManager::AddTextTrack(TextTrackKind aKind, const nsAString& aLabel,
+                               const nsAString& aLanguage)
+{
+  return mTextTracks->AddTextTrack(mMediaElement, aKind, aLabel, aLanguage);
+}
+
+void
+TextTrackManager::AddTextTrack(TextTrack* aTextTrack)
+{
+  mTextTracks->AddTextTrack(aTextTrack);
+}
+
+void
+TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack)
+{
+  mTextTracks->RemoveTextTrack(*aTextTrack);
+}
+
+void
+TextTrackManager::DidSeek()
+{
+  mTextTracks->DidSeek();
+}
+
+void
+TextTrackManager::Update(double aTime)
+{
+  mTextTracks->Update(aTime);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/TextTrackManager.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_TextTrackManager_h
+#define mozilla_dom_TextTrackManager_h
+
+#include "mozilla/dom/TextTrack.h"
+#include "mozilla/dom/TextTrackList.h"
+
+namespace mozilla {
+namespace dom {
+
+class HTMLMediaElement;
+
+class TextTrackManager
+{
+public:
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TextTrackManager)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TextTrackManager);
+
+  TextTrackManager(HTMLMediaElement *aMediaElement);
+  ~TextTrackManager();
+
+  TextTrackList* TextTracks() const;
+  already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
+                                           const nsAString& aLabel,
+                                           const nsAString& aLanguage);
+  void AddTextTrack(TextTrack* aTextTrack);
+  void RemoveTextTrack(TextTrack* aTextTrack);
+  void DidSeek();
+
+  // Update the display of cues on the video as per the current play back time
+  // of aTime.
+  void Update(double aTime);
+
+private:
+  // The HTMLMediaElement that this TextTrackManager manages the TextTracks of.
+  // This is a weak reference as the life time of TextTrackManager is dependent
+  // on the HTMLMediaElement, so it should not be trying to hold the
+  // HTMLMediaElement alive.
+  HTMLMediaElement* mMediaElement;
+  // List of the TextTrackManager's owning HTMLMediaElement's TextTracks.
+  nsRefPtr<TextTrackList> mTextTracks;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TextTrackManager_h
--- a/content/html/content/src/moz.build
+++ b/content/html/content/src/moz.build
@@ -66,16 +66,17 @@ EXPORTS.mozilla.dom += [
     'HTMLTableSectionElement.h',
     'HTMLTemplateElement.h',
     'HTMLTextAreaElement.h',
     'HTMLTimeElement.h',
     'HTMLTitleElement.h',
     'HTMLTrackElement.h',
     'HTMLUnknownElement.h',
     'MediaError.h',
+    'TextTrackManager.h',
     'TimeRanges.h',
     'UndoManager.h',
     'ValidityState.h',
 ]
 
 CPP_SOURCES += [
     'HTMLAnchorElement.cpp',
     'HTMLAreaElement.cpp',
@@ -136,16 +137,17 @@ CPP_SOURCES += [
     'HTMLTemplateElement.cpp',
     'HTMLTextAreaElement.cpp',
     'HTMLTimeElement.cpp',
     'HTMLTitleElement.cpp',
     'HTMLTrackElement.cpp',
     'HTMLUnknownElement.cpp',
     'HTMLVideoElement.cpp',
     'MediaError.cpp',
+    'TextTrackManager.cpp',
     'TimeRanges.cpp',
     'UndoManager.cpp',
     'ValidityState.cpp',
     'nsDOMStringMap.cpp',
     'nsFormSubmission.cpp',
     'nsGenericHTMLElement.cpp',
     'nsGenericHTMLFrameElement.cpp',
     'nsHTMLDNSPrefetch.cpp',