Bug 1417869. P1 - show more descriptive messages for MEDIA_ERR_SRC_NOT_SUPPORTED when SelectResource() fails. draft
authorJW Wang <jwwang@mozilla.com>
Fri, 17 Nov 2017 10:32:41 +0800
changeset 699465 8b75e9c33bc32e76fd3530faf35495cfda84277f
parent 699431 717fe2803a5fc0f7baa678110d41ffe1ebb2b56b
child 699466 a834c50345bef4762953d3a4a0c8e539c19ab495
push id89579
push userjwwang@mozilla.com
push dateFri, 17 Nov 2017 07:15:48 +0000
bugs1417869
milestone59.0a1
Bug 1417869. P1 - show more descriptive messages for MEDIA_ERR_SRC_NOT_SUPPORTED when SelectResource() fails. MozReview-Commit-ID: CySbHaJCaC5
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2033,17 +2033,17 @@ void HTMLMediaElement::SelectResource()
   mIsRunningSelectResource = true;
 
   // If we have a 'src' attribute, use that exclusively.
   nsAutoString src;
   if (mSrcAttrStream) {
     SetupSrcMediaStreamPlayback(mSrcAttrStream);
   } else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
     nsCOMPtr<nsIURI> uri;
-    nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
+    MediaResult rv = NewURIFromString(src, getter_AddRefs(uri));
     if (NS_SUCCEEDED(rv)) {
       LOG(LogLevel::Debug, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
       NS_ASSERTION(!mIsLoadingFromSourceChildren,
         "Should think we're not loading from source children by default");
 
       RemoveMediaElementFromURITable();
       mLoadingSrc = uri;
       mLoadingSrcTriggeringPrincipal = mSrcAttrTriggeringPrincipal;
@@ -2059,23 +2059,26 @@ void HTMLMediaElement::SelectResource()
 
       rv = LoadResource();
       if (NS_SUCCEEDED(rv)) {
         return;
       }
     } else {
       const char16_t* params[] = { src.get() };
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
+      rv = MediaResult(rv.Code(), "MediaLoadInvalidURI");
     }
     // The media element has neither a src attribute nor a source element child:
     // set the networkState to NETWORK_EMPTY, and abort these steps; the
     // synchronous section ends.
     mMainThreadEventTarget->Dispatch(NewRunnableMethod<nsCString>(
       "HTMLMediaElement::NoSupportedMediaSourceError",
-      this, &HTMLMediaElement::NoSupportedMediaSourceError, nsCString()));
+      this,
+      &HTMLMediaElement::NoSupportedMediaSourceError,
+      rv.Description()));
   } else {
     // Otherwise, the source elements will be used.
     mIsLoadingFromSourceChildren = true;
     LoadFromSourceChildren();
   }
 }
 
 void
@@ -2489,32 +2492,33 @@ void HTMLMediaElement::UpdatePreloadActi
       // value "none". The preload value has changed to preload:metadata, so
       // resume the load. We'll pause the load again after we've read the
       // metadata.
       ResumeLoad(PRELOAD_METADATA);
     }
   }
 }
 
-nsresult HTMLMediaElement::LoadResource()
+MediaResult
+HTMLMediaElement::LoadResource()
 {
   AbstractThread::AutoEnter context(AbstractMainThread());
 
   NS_ASSERTION(mDelayingLoadEvent,
                "Should delay load event (if in document) during load");
 
   if (mChannelLoader) {
     mChannelLoader->Cancel();
     mChannelLoader = nullptr;
   }
 
   // Check if media is allowed for the docshell.
   nsCOMPtr<nsIDocShell> docShell = OwnerDoc()->GetDocShell();
   if (docShell && !docShell->GetAllowMedia()) {
-    return NS_ERROR_FAILURE;
+    return MediaResult(NS_ERROR_FAILURE, "Media not allowed");
   }
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
   HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other && other->mDecoder) {
     // Clone it.
@@ -2528,17 +2532,17 @@ nsresult HTMLMediaElement::LoadResource(
   if (IsMediaStreamURI(mLoadingSrc)) {
     RefPtr<DOMMediaStream> stream;
     nsresult rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
     if (NS_FAILED(rv)) {
       nsAutoString spec;
       GetCurrentSrc(spec);
       const char16_t* params[] = { spec.get() };
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
-      return rv;
+      return MediaResult(rv, "MediaLoadInvalidURI");
     }
     SetupSrcMediaStreamPlayback(stream);
     return NS_OK;
   }
 
   if (mMediaSource) {
     MediaDecoderInit decoderInit(
       this,
@@ -2551,37 +2555,38 @@ nsresult HTMLMediaElement::LoadResource(
       MediaContainerType(MEDIAMIMETYPE("application/x.mediasource")));
 
     RefPtr<MediaSourceDecoder> decoder = new MediaSourceDecoder(decoderInit);
     if (!mMediaSource->Attach(decoder)) {
       // TODO: Handle failure: run "If the media data cannot be fetched at
       // all, due to network errors, causing the user agent to give up
       // trying to fetch the resource" section of resource fetch algorithm.
       decoder->Shutdown();
-      return NS_ERROR_FAILURE;
+      return MediaResult(NS_ERROR_FAILURE, "Failed to attach MediaSource");
     }
     ChangeDelayLoadStatus(false);
     nsresult rv = decoder->Load(mMediaSource->GetPrincipal());
     if (NS_FAILED(rv)) {
       decoder->Shutdown();
       LOG(LogLevel::Debug,
           ("%p Failed to load for decoder %p", this, decoder.get()));
-      return rv;
-    }
-    return FinishDecoderSetup(decoder);
+      return MediaResult(rv, "Fail to load decoder");
+    }
+    rv = FinishDecoderSetup(decoder);
+    return MediaResult(rv, "Failed to set up decoder");
   }
 
   AssertReadyStateIsNothing();
 
   RefPtr<ChannelLoader> loader = new ChannelLoader;
   nsresult rv = loader->Load(this);
   if (NS_SUCCEEDED(rv)) {
     mChannelLoader = loader.forget();
   }
-  return rv;
+  return MediaResult(rv, "Failed to load channel");
 }
 
 nsresult HTMLMediaElement::LoadWithChannel(nsIChannel* aChannel,
                                            nsIStreamListener** aListener)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_ENSURE_ARG_POINTER(aListener);
 
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1050,17 +1050,17 @@ protected:
    * When loading a new source on an existing media element, make sure to reset
    * everything that is accessible using the media element API.
    */
   void ResetState();
 
   /**
    * The resource-fetch algorithm step of the load algorithm.
    */
-  nsresult LoadResource();
+  MediaResult LoadResource();
 
   /**
    * Selects the next <source> child from which to load a resource. Called
    * during the resource selection algorithm. Stores the return value in
    * mSourceLoadCandidate before returning.
    */
   nsIContent* GetNextSource();