Bug 1417869. P3 - pass descriptive messages to NetworkError(). draft
authorJW Wang <jwwang@mozilla.com>
Fri, 17 Nov 2017 11:07:30 +0800
changeset 699467 66033fd9413f28415d19ac243a15e068b6edc767
parent 699466 a834c50345bef4762953d3a4a0c8e539c19ab495
child 740635 d2101ca2df0b07dbb74b1cc837473924dd35fbfa
push id89579
push userjwwang@mozilla.com
push dateFri, 17 Nov 2017 07:15:48 +0000
bugs1417869
milestone59.0a1
Bug 1417869. P3 - pass descriptive messages to NetworkError(). MozReview-Commit-ID: 6yaFJvXG3g8
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/media/ChannelMediaDecoder.cpp
dom/media/ChannelMediaDecoder.h
dom/media/ChannelMediaResource.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderOwner.h
dom/media/MediaResourceCallback.h
dom/media/hls/HLSDecoder.cpp
dom/media/mediasource/MediaSource.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2406,18 +2406,19 @@ void HTMLMediaElement::ResumeLoad(Preloa
   NS_ASSERTION(mSuspendedForPreloadNone,
     "Must be halted for preload:none to resume from preload:none suspended load.");
   mSuspendedForPreloadNone = false;
   mPreloadAction = aAction;
   ChangeDelayLoadStatus(true);
   ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
   if (!mIsLoadingFromSourceChildren) {
     // We were loading from the element's src attribute.
-    if (NS_FAILED(LoadResource())) {
-      NoSupportedMediaSourceError();
+    MediaResult rv = LoadResource();
+    if (NS_FAILED(rv)) {
+      NoSupportedMediaSourceError(rv.Description());
     }
   } else {
     // We were loading from a child <source> element. Try to resume the
     // load of that child, and if that fails, try the next child.
     if (NS_FAILED(LoadResource())) {
       LoadFromSourceChildren();
     }
   }
@@ -5535,20 +5536,21 @@ void HTMLMediaElement::FirstFrameLoaded(
   if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
       !HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
       mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
     mSuspendedAfterFirstFrame = true;
     mDecoder->Suspend();
   }
 }
 
-void HTMLMediaElement::NetworkError()
+void
+HTMLMediaElement::NetworkError(const MediaResult& aError)
 {
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
-    NoSupportedMediaSourceError();
+    NoSupportedMediaSourceError(aError.Description());
   } else {
     Error(MEDIA_ERR_NETWORK);
   }
 }
 
 void HTMLMediaElement::DecodeError(const MediaResult& aError)
 {
   nsAutoString src;
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -169,17 +169,17 @@ public:
     UniquePtr<const MetadataTags> aTags) final override;
 
   // Called by the decoder object, on the main thread,
   // when it has read the first frame of the video or audio.
   virtual void FirstFrameLoaded() final override;
 
   // Called by the video decoder object, on the main thread,
   // when the resource has a network error during loading.
-  virtual void NetworkError() final override;
+  virtual void NetworkError(const MediaResult& aError) final override;
 
   // Called by the video decoder object, on the main thread, when the
   // resource has a decode error during metadata loading or decoding.
   virtual void DecodeError(const MediaResult& aError) final override;
 
   // Called by the decoder object, on the main thread, when the
   // resource has a decode issue during metadata loading or decoding, but can
   // continue decoding.
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -53,21 +53,22 @@ ChannelMediaDecoder::ResourceCallback::A
 MediaDecoderOwner*
 ChannelMediaDecoder::ResourceCallback::GetMediaOwner() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   return mDecoder ? mDecoder->GetOwner() : nullptr;
 }
 
 void
-ChannelMediaDecoder::ResourceCallback::NotifyNetworkError()
+ChannelMediaDecoder::ResourceCallback::NotifyNetworkError(
+  const MediaResult& aError)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mDecoder) {
-    mDecoder->NetworkError();
+    mDecoder->NetworkError(aError);
   }
 }
 
 /* static */ void
 ChannelMediaDecoder::ResourceCallback::TimerCallback(nsITimer* aTimer,
                                                      void* aClosure)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -301,17 +302,17 @@ ChannelMediaDecoder::NotifyDownloadEnded
     // NotifySuspendedStatusChanged will tell the element that download
     // has been suspended "by the cache", which is true since we never
     // download anything. The element can then transition to HAVE_ENOUGH_DATA.
     owner->NotifySuspendedByCache(true);
   } else if (aStatus == NS_BINDING_ABORTED) {
     // Download has been cancelled by user.
     owner->LoadAborted();
   } else {
-    NetworkError();
+    NetworkError(MediaResult(aStatus, "Download aborted"));
   }
 }
 
 void
 ChannelMediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
--- a/dom/media/ChannelMediaDecoder.h
+++ b/dom/media/ChannelMediaDecoder.h
@@ -34,17 +34,17 @@ class ChannelMediaDecoder : public Media
     void Connect(ChannelMediaDecoder* aDecoder);
     // Called upon shutdown to stop receiving notifications.
     void Disconnect();
 
   private:
     /* MediaResourceCallback functions */
     AbstractThread* AbstractMainThread() const override;
     MediaDecoderOwner* GetMediaOwner() const override;
-    void NotifyNetworkError() override;
+    void NotifyNetworkError(const MediaResult& aError) override;
     void NotifyDataArrived() override;
     void NotifyDataEnded(nsresult aStatus) override;
     void NotifyPrincipalChanged() override;
     void NotifySuspendedStatusChanged(bool aSuspendedByCache) override;
     void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) override;
 
     static void TimerCallback(nsITimer* aTimer, void* aClosure);
 
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -180,17 +180,17 @@ ChannelMediaResource::OnStartRequest(nsI
     CloseChannel();
     return status;
   }
 
   if (element->ShouldCheckAllowOrigin()) {
     // If the request was cancelled by nsCORSListenerProxy due to failing
     // the CORS security check, send an error through to the media element.
     if (status == NS_ERROR_DOM_BAD_URI) {
-      mCallback->NotifyNetworkError();
+      mCallback->NotifyNetworkError(MediaResult(status, "CORS not allowed"));
       return NS_ERROR_DOM_BAD_URI;
     }
   }
 
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(aRequest);
   bool seekable = false;
   int64_t startOffset = aRequestOffset;
 
@@ -210,17 +210,18 @@ ChannelMediaResource::OnStartRequest(nsI
       // suspend and resume, the resume reopens the channel and we seek to
       // offset N, but there are no more bytes, so we get a 416
       // "Requested Range Not Satisfiable".
       if (responseStatus == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE) {
         // OnStopRequest will not be fired, so we need to do some of its
         // work here.
         mCacheStream.NotifyDataEnded(status);
       } else {
-        mCallback->NotifyNetworkError();
+        mCallback->NotifyNetworkError(
+          MediaResult(NS_ERROR_FAILURE, "HTTP error"));
       }
 
       // This disconnects our listener so we don't get any more data. We
       // certainly don't want an error page to end up in our cache!
       CloseChannel();
       return NS_OK;
     }
 
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -860,21 +860,21 @@ MediaDecoder::FirstFrameLoaded(nsAutoPtr
   // GetOwner()->FirstFrameLoaded() might call us back. Put it at the bottom of
   // this function to avoid unexpected shutdown from reentrant calls.
   if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) {
     GetOwner()->FirstFrameLoaded();
   }
 }
 
 void
-MediaDecoder::NetworkError()
+MediaDecoder::NetworkError(const MediaResult& aError)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-  GetOwner()->NetworkError();
+  GetOwner()->NetworkError(aError);
 }
 
 void
 MediaDecoder::DecodeError(const MediaResult& aError)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
   GetOwner()->DecodeError(aError);
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -111,17 +111,17 @@ public:
   virtual void Shutdown();
 
   // Notified by the shutdown manager that XPCOM shutdown has begun.
   // The decoder should notify its owner to drop the reference to the decoder
   // to prevent further calls into the decoder.
   void NotifyXPCOMShutdown();
 
   // Called if the media file encounters a network error.
-  void NetworkError();
+  void NetworkError(const MediaResult& aError);
 
   // Return the principal of the current URI being played or downloaded.
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
 
   // Return the time position in the video stream being
   // played measured in seconds.
   virtual double GetCurrentTime();
 
--- a/dom/media/MediaDecoderOwner.h
+++ b/dom/media/MediaDecoderOwner.h
@@ -58,17 +58,17 @@ public:
   // Called by the decoder object, on the main thread,
   // when it has read the first frame of the video or audio.
   virtual void FirstFrameLoaded() = 0;
 
   // Called by the decoder object, on the main thread,
   // when the resource has a network error during loading.
   // The decoder owner should call Shutdown() on the decoder and drop the
   // reference to the decoder to prevent further calls into the decoder.
-  virtual void NetworkError() = 0;
+  virtual void NetworkError(const MediaResult& aError) = 0;
 
   // Called by the decoder object, on the main thread, when the
   // resource has a decode error during metadata loading or decoding.
   // The decoder owner should call Shutdown() on the decoder and drop the
   // reference to the decoder to prevent further calls into the decoder.
   virtual void DecodeError(const MediaResult& aError) = 0;
 
   // Called by the decoder object, on the main thread, when the
--- a/dom/media/MediaResourceCallback.h
+++ b/dom/media/MediaResourceCallback.h
@@ -4,16 +4,17 @@
  * 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 MediaResourceCallback_h_
 #define MediaResourceCallback_h_
 
 #include "nsError.h"
 #include "nsISupportsImpl.h"
+#include "MediaResult.h"
 
 namespace mozilla {
 
 class AbstractThread;
 class MediaDecoderOwner;
 class MediaResource;
 
 /**
@@ -31,17 +32,17 @@ public:
 
   // Return an abstract thread on which to run main thread runnables.
   virtual AbstractThread* AbstractMainThread() const { return nullptr; }
 
   // Returns a weak reference to the media decoder owner.
   virtual MediaDecoderOwner* GetMediaOwner() const { return nullptr; }
 
   // Notify that a network error is encountered.
-  virtual void NotifyNetworkError() {}
+  virtual void NotifyNetworkError(const MediaResult& aError) {}
 
   // Notify that data arrives on the stream and is read into the cache.
   virtual void NotifyDataArrived() {}
 
   // Notify download is ended.
   // NOTE: this can be called with the media cache lock held, so don't
   // block or do anything which might try to acquire a lock!
   virtual void NotifyDataEnded(nsresult aStatus) {}
--- a/dom/media/hls/HLSDecoder.cpp
+++ b/dom/media/hls/HLSDecoder.cpp
@@ -89,17 +89,18 @@ HLSResourceCallbacksSupport::OnError(int
   NS_DispatchToMainThread(
     NS_NewRunnableFunction(
       "HLSResourceCallbacksSupport::OnDataArrived",
       [self]() -> void {
         MutexAutoLock lock(self->mMutex);
         if (self->mDecoder) {
           // Since HLS source should be from the Internet, we treat all resource errors
           // from GeckoHlsPlayer as network errors.
-          self->mDecoder->NetworkError();
+          self->mDecoder->NetworkError(
+            MediaResult(NS_ERROR_FAILURE, "HLS error"));
         }
       }
     )
   );
 }
 
 HLSDecoder::HLSDecoder(MediaDecoderInit& aInit)
   : MediaDecoder(aInit)
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -355,17 +355,17 @@ MediaSource::EndOfStream(const Optional<
   if (!aError.WasPassed()) {
     DurationChange(mSourceBuffers->GetHighestBufferedEndTime(), aRv);
     // Notify reader that all data is now available.
     mDecoder->Ended(true);
     return;
   }
   switch (aError.Value()) {
   case MediaSourceEndOfStreamError::Network:
-    mDecoder->NetworkError();
+    mDecoder->NetworkError(MediaResult(NS_ERROR_FAILURE, "MSE network"));
     break;
   case MediaSourceEndOfStreamError::Decode:
     mDecoder->DecodeError(NS_ERROR_DOM_MEDIA_FATAL_ERR);
     break;
   default:
     aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
   }
 }