Bug 1394705 - let HTMLMediaElement::MediaLoadListener implement nsIThreadRetargetableStreamListener. draft
authorJW Wang <jwwang@mozilla.com>
Tue, 29 Aug 2017 14:28:13 +0800
changeset 654761 b3e30aee238a522a0b4129cb606ecb48264de5ca
parent 654744 c525cc941fb2504eee00b8237defe5fef2eea934
child 728651 26fc4a232d95656b2c2a20aef6569ecf976cfb1c
push id76670
push userjwwang@mozilla.com
push dateTue, 29 Aug 2017 07:37:33 +0000
bugs1394705
milestone57.0a1
Bug 1394705 - let HTMLMediaElement::MediaLoadListener implement nsIThreadRetargetableStreamListener. This is required to use nsIThreadRetargetableRequest::RetargetDeliveryTo(). MozReview-Commit-ID: GFuAjovabpY
dom/html/HTMLMediaElement.cpp
dom/media/MediaResource.cpp
dom/media/MediaResource.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -444,47 +444,54 @@ private:
 };
 
 /**
  * There is a reference cycle involving this class: MediaLoadListener
  * holds a reference to the HTMLMediaElement, which holds a reference
  * to an nsIChannel, which holds a reference to this listener.
  * We break the reference cycle in OnStartRequest by clearing mElement.
  */
-class HTMLMediaElement::MediaLoadListener final : public nsIStreamListener,
-                                                  public nsIChannelEventSink,
-                                                  public nsIInterfaceRequestor,
-                                                  public nsIObserver
+class HTMLMediaElement::MediaLoadListener final
+  : public nsIStreamListener
+  , public nsIChannelEventSink
+  , public nsIInterfaceRequestor
+  , public nsIObserver
+  , public nsIThreadRetargetableStreamListener
 {
   ~MediaLoadListener() {}
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
 
 public:
   explicit MediaLoadListener(HTMLMediaElement* aElement)
     : mElement(aElement),
       mLoadID(aElement->GetCurrentLoadID())
   {
     MOZ_ASSERT(mElement, "Must pass an element to call back");
   }
 
 private:
   RefPtr<HTMLMediaElement> mElement;
   nsCOMPtr<nsIStreamListener> mNextListener;
   const uint32_t mLoadID;
 };
 
-NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
-                  nsIStreamListener, nsIChannelEventSink,
-                  nsIInterfaceRequestor, nsIObserver)
+NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener,
+                  nsIRequestObserver,
+                  nsIStreamListener,
+                  nsIChannelEventSink,
+                  nsIInterfaceRequestor,
+                  nsIObserver,
+                  nsIThreadRetargetableStreamListener)
 
 NS_IMETHODIMP
 HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
                                              const char* aTopic,
                                              const char16_t* aData)
 {
   nsContentUtils::UnregisterShutdownObserver(this);
 
@@ -617,16 +624,28 @@ HTMLMediaElement::MediaLoadListener::Asy
   if (sink) {
     return sink->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, cb);
   }
   cb->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+HTMLMediaElement::MediaLoadListener::CheckListenerChain()
+{
+  MOZ_ASSERT(mNextListener);
+  nsCOMPtr<nsIThreadRetargetableStreamListener> retargetable =
+    do_QueryInterface(mNextListener);
+  if (retargetable) {
+    return retargetable->CheckListenerChain();
+  }
+  return NS_ERROR_NO_INTERFACE;
+}
+
+NS_IMETHODIMP
 HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID& aIID,
                                                   void** aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
 void HTMLMediaElement::ReportLoadError(const char* aMsg,
                                        const char16_t** aParams,
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -117,18 +117,21 @@ ChannelMediaResource::~ChannelMediaResou
 
 // ChannelMediaResource::Listener just observes the channel and
 // forwards notifications to the ChannelMediaResource. We use multiple
 // listener objects so that when we open a new stream for a seek we can
 // disconnect the old listener from the ChannelMediaResource and hook up
 // a new listener, so notifications from the old channel are discarded
 // and don't confuse us.
 NS_IMPL_ISUPPORTS(ChannelMediaResource::Listener,
-                  nsIRequestObserver, nsIStreamListener, nsIChannelEventSink,
-                  nsIInterfaceRequestor)
+                  nsIRequestObserver,
+                  nsIStreamListener,
+                  nsIChannelEventSink,
+                  nsIInterfaceRequestor,
+                  nsIThreadRetargetableStreamListener)
 
 nsresult
 ChannelMediaResource::Listener::OnStartRequest(nsIRequest* aRequest,
                                                nsISupports* aContext)
 {
   if (!mResource)
     return NS_OK;
   return mResource->OnStartRequest(aRequest);
@@ -169,17 +172,23 @@ ChannelMediaResource::Listener::AsyncOnC
   if (NS_FAILED(rv))
     return rv;
 
   cb->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
 nsresult
-ChannelMediaResource::Listener::GetInterface(const nsIID & aIID, void **aResult)
+ChannelMediaResource::Listener::CheckListenerChain()
+{
+  return NS_OK;
+}
+
+nsresult
+ChannelMediaResource::Listener::GetInterface(const nsIID& aIID, void** aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
 static bool
 IsPayloadCompressed(nsIHttpChannel* aChannel)
 {
   nsAutoCString encoding;
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -8,16 +8,17 @@
 
 #include "mozilla/Mutex.h"
 #include "nsIChannel.h"
 #include "nsIURI.h"
 #include "nsISeekableStream.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
+#include "nsIThreadRetargetableStreamListener.h"
 #include "Intervals.h"
 #include "MediaCache.h"
 #include "MediaContainerType.h"
 #include "MediaData.h"
 #include "MediaPrefs.h"
 #include "MediaResourceCallback.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
@@ -498,29 +499,32 @@ public:
 
     return size;
   }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
-  class Listener final : public nsIStreamListener,
-                         public nsIInterfaceRequestor,
-                         public nsIChannelEventSink
+  class Listener final
+    : public nsIStreamListener
+    , public nsIInterfaceRequestor
+    , public nsIChannelEventSink
+    , public nsIThreadRetargetableStreamListener
   {
     ~Listener() {}
   public:
     explicit Listener(ChannelMediaResource* aResource) : mResource(aResource) {}
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSICHANNELEVENTSINK
     NS_DECL_NSIINTERFACEREQUESTOR
+    NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
 
     void Revoke() { mResource = nullptr; }
 
   private:
     RefPtr<ChannelMediaResource> mResource;
   };
   friend class Listener;