Bug 1116676 - Ensure that AddRemoveSelfReference() is called on networkState changes. r=roc, a=sledru
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 31 Dec 2014 16:34:56 +1300
changeset 242839 ad2cfe2a92a5
parent 242838 f6d5f2303fea
child 242840 44e174f9d843
push id4320
push userryanvm@gmail.com
push date2015-01-14 14:48 +0000
treeherdermozilla-beta@06bb4d89e2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs1116676
milestone36.0
Bug 1116676 - Ensure that AddRemoveSelfReference() is called on networkState changes. r=roc, a=sledru Now that mDelayingLoadEvent may already be false when NoSupportedMediaSourceError() is called, ChangeDelayLoadStatus(false) won't necessarily call AddRemoveSelfReference().
dom/html/HTMLMediaElement.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -678,32 +678,31 @@ void HTMLMediaElement::AbortExistingLoad
       // will now be reported as 0. The playback position was non-zero when
       // we destroyed the decoder, so fire a timeupdate event so that the
       // change will be reflected in the controls.
       FireTimeUpdate(false);
     }
     DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
   }
 
-  // We may have changed mPaused, mAutoplaying, mNetworkState and other
+  // We may have changed mPaused, mAutoplaying, and other
   // things which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   mIsRunningSelectResource = false;
 }
 
 void HTMLMediaElement::NoSupportedMediaSourceError()
 {
   NS_ASSERTION(mNetworkState == NETWORK_LOADING,
                "Not loading during source selection?");
 
   mError = new MediaError(this, nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE);
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
-  // This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
   ChangeDelayLoadStatus(false);
 }
 
 typedef void (HTMLMediaElement::*SyncSectionFn)();
 
 // Runs a "synchronous section", a function that must run once the event loop
 // has reached a "stable state". See:
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#synchronous-section
@@ -808,26 +807,23 @@ void HTMLMediaElement::SelectResourceWra
 
 void HTMLMediaElement::SelectResource()
 {
   if (!mSrcAttrStream && !HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
       !HasSourceChildren(this)) {
     // The media element has neither a src attribute nor any source
     // element children, abort the load.
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
-    // This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
     ChangeDelayLoadStatus(false);
     return;
   }
 
   ChangeDelayLoadStatus(true);
 
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
-  // Load event was delayed, and still is, so no need to call
-  // AddRemoveSelfReference, since it must still be held
   DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
 
   // Delay setting mIsRunningSeletResource until after UpdatePreloadAction
   // so that we don't lose our state change by bailing out of the preload
   // state update
   UpdatePreloadAction();
   mIsRunningSelectResource = true;
 
@@ -2126,17 +2122,16 @@ void HTMLMediaElement::SetPlayedOrSeeked
 
 void
 HTMLMediaElement::ResetConnectionState()
 {
   SetCurrentTime(0);
   FireTimeUpdate(false);
   DispatchAsyncEvent(NS_LITERAL_STRING("ended"));
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
-  AddRemoveSelfReference();
   ChangeDelayLoadStatus(false);
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
 }
 
 void
 HTMLMediaElement::Play(ErrorResult& aRv)
 {
   StopSuspendingAfterFirstFrame();
@@ -2851,17 +2846,16 @@ void HTMLMediaElement::SetupSrcMediaStre
   // Note: we must call DisconnectTrackListListeners(...)  before dropping
   // mSrcStream
   mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks());
 
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
-  AddRemoveSelfReference();
   // FirstFrameLoaded() will be called when the stream has current data.
 }
 
 void HTMLMediaElement::EndSrcMediaStreamPlayback()
 {
   MediaStream* stream = GetSrcMediaStream();
   if (stream) {
     stream->RemoveListener(mSrcStreamListener);
@@ -2987,17 +2981,16 @@ void HTMLMediaElement::Error(uint16_t aE
   mError = new MediaError(this, aErrorCode);
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
     DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
   } else {
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
   }
-  AddRemoveSelfReference();
   ChangeDelayLoadStatus(false);
 }
 
 void HTMLMediaElement::PlaybackEnded()
 {
   // We changed state which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
@@ -3061,25 +3054,23 @@ void HTMLMediaElement::NotifySuspendedBy
 
 void HTMLMediaElement::DownloadSuspended()
 {
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING) {
     DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
   }
   if (mBegun) {
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
-    AddRemoveSelfReference();
   }
 }
 
 void HTMLMediaElement::DownloadResumed(bool aForceNetworkLoading)
 {
   if (mBegun || aForceNetworkLoading) {
     ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
-    AddRemoveSelfReference();
   }
 }
 
 void HTMLMediaElement::CheckProgress(bool aHaveNewProgress)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING);
 
@@ -3335,16 +3326,19 @@ void HTMLMediaElement::ChangeNetworkStat
     // Download is begun.
     mBegun = true;
     // Start progress notification when entering NETWORK_LOADING.
     StartProgress();
   } else if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_IDLE && !mError) {
     // Fire 'suspend' event when entering NETWORK_IDLE and no error presented.
     DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   }
+
+  // Changing mNetworkState affects AddRemoveSelfReference().
+  AddRemoveSelfReference();
 }
 
 bool HTMLMediaElement::CanActivateAutoplay()
 {
   // For stream inputs, we activate autoplay on HAVE_CURRENT_DATA because
   // this element itself might be blocking the stream from making progress by
   // being paused.
   return !mPausedForInactiveDocumentOrChannel &&