LCOV - code coverage report
Current view: top level - netwerk/protocol/websocket - WebSocketEventService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 5 244 2.0 %
Date: 2017-07-14 16:53:18 Functions: 1 49 2.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "WebSocketEventListenerChild.h"
       8             : #include "WebSocketEventService.h"
       9             : #include "WebSocketFrame.h"
      10             : 
      11             : #include "mozilla/net/NeckoChild.h"
      12             : #include "mozilla/StaticPtr.h"
      13             : #include "nsISupportsPrimitives.h"
      14             : #include "nsIObserverService.h"
      15             : #include "nsXULAppAPI.h"
      16             : #include "nsSocketTransportService2.h"
      17             : #include "nsThreadUtils.h"
      18             : #include "mozilla/Services.h"
      19             : 
      20             : namespace mozilla {
      21             : namespace net {
      22             : 
      23             : namespace {
      24             : 
      25           3 : StaticRefPtr<WebSocketEventService> gWebSocketEventService;
      26             : 
      27             : bool
      28           0 : IsChildProcess()
      29             : {
      30           0 :   return XRE_GetProcessType() != GeckoProcessType_Default;
      31             : }
      32             : 
      33             : } // anonymous namespace
      34             : 
      35             : class WebSocketBaseRunnable : public Runnable
      36             : {
      37             : public:
      38           0 :   WebSocketBaseRunnable(uint32_t aWebSocketSerialID, uint64_t aInnerWindowID)
      39           0 :     : Runnable("net::WebSocketBaseRunnable")
      40             :     , mWebSocketSerialID(aWebSocketSerialID)
      41           0 :     , mInnerWindowID(aInnerWindowID)
      42           0 :   {}
      43             : 
      44           0 :   NS_IMETHOD Run() override
      45             :   {
      46           0 :     MOZ_ASSERT(NS_IsMainThread());
      47             : 
      48           0 :     RefPtr<WebSocketEventService> service = WebSocketEventService::GetOrCreate();
      49           0 :     MOZ_ASSERT(service);
      50             : 
      51           0 :     WebSocketEventService::WindowListeners listeners;
      52           0 :     service->GetListeners(mInnerWindowID, listeners);
      53             : 
      54           0 :     for (uint32_t i = 0; i < listeners.Length(); ++i) {
      55           0 :       DoWork(listeners[i]);
      56             :     }
      57             : 
      58           0 :     return NS_OK;
      59             :   }
      60             : 
      61             : protected:
      62           0 :   ~WebSocketBaseRunnable()
      63           0 :   {}
      64             : 
      65             :   virtual void DoWork(nsIWebSocketEventListener* aListener) = 0;
      66             : 
      67             :   uint32_t mWebSocketSerialID;
      68             :   uint64_t mInnerWindowID;
      69             : };
      70             : 
      71           0 : class WebSocketFrameRunnable final : public WebSocketBaseRunnable
      72             : {
      73             : public:
      74           0 :   WebSocketFrameRunnable(uint32_t aWebSocketSerialID,
      75             :                          uint64_t aInnerWindowID,
      76             :                          already_AddRefed<WebSocketFrame> aFrame,
      77             :                          bool aFrameSent)
      78           0 :     : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
      79           0 :     , mFrame(Move(aFrame))
      80           0 :     , mFrameSent(aFrameSent)
      81           0 :   {}
      82             : 
      83             : private:
      84           0 :   virtual void DoWork(nsIWebSocketEventListener* aListener) override
      85             :   {
      86           0 :     DebugOnly<nsresult> rv;
      87           0 :     if (mFrameSent) {
      88           0 :       rv = aListener->FrameSent(mWebSocketSerialID, mFrame);
      89             :     } else {
      90           0 :       rv = aListener->FrameReceived(mWebSocketSerialID, mFrame);
      91             :     }
      92             : 
      93           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Frame op failed");
      94           0 :   }
      95             : 
      96             :   RefPtr<WebSocketFrame> mFrame;
      97             :   bool mFrameSent;
      98             : };
      99             : 
     100           0 : class WebSocketCreatedRunnable final : public WebSocketBaseRunnable
     101             : {
     102             : public:
     103           0 :   WebSocketCreatedRunnable(uint32_t aWebSocketSerialID,
     104             :                            uint64_t aInnerWindowID,
     105             :                            const nsAString& aURI,
     106             :                            const nsACString& aProtocols)
     107           0 :     : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
     108             :     , mURI(aURI)
     109           0 :     , mProtocols(aProtocols)
     110           0 :   {}
     111             : 
     112             : private:
     113           0 :   virtual void DoWork(nsIWebSocketEventListener* aListener) override
     114             :   {
     115             :     DebugOnly<nsresult> rv =
     116           0 :       aListener->WebSocketCreated(mWebSocketSerialID, mURI, mProtocols);
     117           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WebSocketCreated failed");
     118           0 :   }
     119             : 
     120             :   const nsString mURI;
     121             :   const nsCString mProtocols;
     122             : };
     123             : 
     124           0 : class WebSocketOpenedRunnable final : public WebSocketBaseRunnable
     125             : {
     126             : public:
     127           0 :   WebSocketOpenedRunnable(uint32_t aWebSocketSerialID,
     128             :                            uint64_t aInnerWindowID,
     129             :                            const nsAString& aEffectiveURI,
     130             :                            const nsACString& aProtocols,
     131             :                            const nsACString& aExtensions)
     132           0 :     : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
     133             :     , mEffectiveURI(aEffectiveURI)
     134             :     , mProtocols(aProtocols)
     135           0 :     , mExtensions(aExtensions)
     136           0 :   {}
     137             : 
     138             : private:
     139           0 :   virtual void DoWork(nsIWebSocketEventListener* aListener) override
     140             :   {
     141           0 :     DebugOnly<nsresult> rv = aListener->WebSocketOpened(mWebSocketSerialID,
     142             :                                                         mEffectiveURI,
     143             :                                                         mProtocols,
     144           0 :                                                         mExtensions);
     145           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WebSocketOpened failed");
     146           0 :   }
     147             : 
     148             :   const nsString mEffectiveURI;
     149             :   const nsCString mProtocols;
     150             :   const nsCString mExtensions;
     151             : };
     152             : 
     153           0 : class WebSocketMessageAvailableRunnable final : public WebSocketBaseRunnable
     154             : {
     155             : public:
     156           0 :   WebSocketMessageAvailableRunnable(uint32_t aWebSocketSerialID,
     157             :                           uint64_t aInnerWindowID,
     158             :                           const nsACString& aData,
     159             :                           uint16_t aMessageType)
     160           0 :     : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
     161             :     , mData(aData)
     162           0 :     , mMessageType(aMessageType)
     163           0 :   {}
     164             : 
     165             : private:
     166           0 :   virtual void DoWork(nsIWebSocketEventListener* aListener) override
     167             :   {
     168             :     DebugOnly<nsresult> rv =
     169           0 :       aListener->WebSocketMessageAvailable(mWebSocketSerialID, mData,
     170           0 :                                            mMessageType);
     171           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WebSocketMessageAvailable failed");
     172           0 :   }
     173             : 
     174             :   const nsCString mData;
     175             :   uint16_t mMessageType;
     176             : };
     177             : 
     178           0 : class WebSocketClosedRunnable final : public WebSocketBaseRunnable
     179             : {
     180             : public:
     181           0 :   WebSocketClosedRunnable(uint32_t aWebSocketSerialID,
     182             :                           uint64_t aInnerWindowID,
     183             :                           bool aWasClean,
     184             :                           uint16_t aCode,
     185             :                           const nsAString& aReason)
     186           0 :     : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
     187             :     , mWasClean(aWasClean)
     188             :     , mCode(aCode)
     189           0 :     , mReason(aReason)
     190           0 :   {}
     191             : 
     192             : private:
     193           0 :   virtual void DoWork(nsIWebSocketEventListener* aListener) override
     194             :   {
     195             :     DebugOnly<nsresult> rv =
     196           0 :       aListener->WebSocketClosed(mWebSocketSerialID, mWasClean, mCode, mReason);
     197           0 :     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WebSocketClosed failed");
     198           0 :   }
     199             : 
     200             :   bool mWasClean;
     201             :   uint16_t mCode;
     202             :   const nsString mReason;
     203             : };
     204             : 
     205             : /* static */ already_AddRefed<WebSocketEventService>
     206           4 : WebSocketEventService::Get()
     207             : {
     208           4 :   MOZ_ASSERT(NS_IsMainThread());
     209           8 :   RefPtr<WebSocketEventService> service = gWebSocketEventService.get();
     210           8 :   return service.forget();
     211             : }
     212             : 
     213             : /* static */ already_AddRefed<WebSocketEventService>
     214           0 : WebSocketEventService::GetOrCreate()
     215             : {
     216           0 :   MOZ_ASSERT(NS_IsMainThread());
     217             : 
     218           0 :   if (!gWebSocketEventService) {
     219           0 :     gWebSocketEventService = new WebSocketEventService();
     220             :   }
     221             : 
     222           0 :   RefPtr<WebSocketEventService> service = gWebSocketEventService.get();
     223           0 :   return service.forget();
     224             : }
     225             : 
     226           0 : NS_INTERFACE_MAP_BEGIN(WebSocketEventService)
     227           0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebSocketEventService)
     228           0 :   NS_INTERFACE_MAP_ENTRY(nsIObserver)
     229           0 :   NS_INTERFACE_MAP_ENTRY(nsIWebSocketEventService)
     230           0 : NS_INTERFACE_MAP_END
     231             : 
     232           0 : NS_IMPL_ADDREF(WebSocketEventService)
     233           0 : NS_IMPL_RELEASE(WebSocketEventService)
     234             : 
     235           0 : WebSocketEventService::WebSocketEventService()
     236           0 :   : mCountListeners(0)
     237             : {
     238           0 :   MOZ_ASSERT(NS_IsMainThread());
     239             : 
     240           0 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     241           0 :   if (obs) {
     242           0 :     obs->AddObserver(this, "xpcom-shutdown", false);
     243           0 :     obs->AddObserver(this, "inner-window-destroyed", false);
     244             :   }
     245           0 : }
     246             : 
     247           0 : WebSocketEventService::~WebSocketEventService()
     248             : {
     249           0 :   MOZ_ASSERT(NS_IsMainThread());
     250           0 : }
     251             : 
     252             : void
     253           0 : WebSocketEventService::WebSocketCreated(uint32_t aWebSocketSerialID,
     254             :                                         uint64_t aInnerWindowID,
     255             :                                         const nsAString& aURI,
     256             :                                         const nsACString& aProtocols,
     257             :                                         nsIEventTarget* aTarget)
     258             : {
     259             :   // Let's continue only if we have some listeners.
     260           0 :   if (!HasListeners()) {
     261           0 :     return;
     262             :   }
     263             : 
     264             :   RefPtr<WebSocketCreatedRunnable> runnable =
     265             :     new WebSocketCreatedRunnable(aWebSocketSerialID, aInnerWindowID,
     266           0 :                                  aURI, aProtocols);
     267             :   DebugOnly<nsresult> rv = aTarget
     268           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     269           0 :     : NS_DispatchToMainThread(runnable);
     270           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     271             : }
     272             : 
     273             : void
     274           0 : WebSocketEventService::WebSocketOpened(uint32_t aWebSocketSerialID,
     275             :                                        uint64_t aInnerWindowID,
     276             :                                        const nsAString& aEffectiveURI,
     277             :                                        const nsACString& aProtocols,
     278             :                                        const nsACString& aExtensions,
     279             :                                        nsIEventTarget* aTarget)
     280             : {
     281             :   // Let's continue only if we have some listeners.
     282           0 :   if (!HasListeners()) {
     283           0 :     return;
     284             :   }
     285             : 
     286             :   RefPtr<WebSocketOpenedRunnable> runnable =
     287             :     new WebSocketOpenedRunnable(aWebSocketSerialID, aInnerWindowID,
     288           0 :                                 aEffectiveURI, aProtocols, aExtensions);
     289             :   DebugOnly<nsresult> rv = aTarget
     290           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     291           0 :     : NS_DispatchToMainThread(runnable);
     292           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     293             : }
     294             : 
     295             : void
     296           0 : WebSocketEventService::WebSocketMessageAvailable(uint32_t aWebSocketSerialID,
     297             :                                                  uint64_t aInnerWindowID,
     298             :                                                  const nsACString& aData,
     299             :                                                  uint16_t aMessageType,
     300             :                                                  nsIEventTarget* aTarget)
     301             : {
     302             :   // Let's continue only if we have some listeners.
     303           0 :   if (!HasListeners()) {
     304           0 :     return;
     305             :   }
     306             : 
     307             :   RefPtr<WebSocketMessageAvailableRunnable> runnable =
     308             :     new WebSocketMessageAvailableRunnable(aWebSocketSerialID, aInnerWindowID,
     309           0 :                                           aData, aMessageType);
     310             :   DebugOnly<nsresult> rv = aTarget
     311           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     312           0 :     : NS_DispatchToMainThread(runnable);
     313           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     314             : }
     315             : 
     316             : void
     317           0 : WebSocketEventService::WebSocketClosed(uint32_t aWebSocketSerialID,
     318             :                                        uint64_t aInnerWindowID,
     319             :                                        bool aWasClean,
     320             :                                        uint16_t aCode,
     321             :                                        const nsAString& aReason,
     322             :                                        nsIEventTarget* aTarget)
     323             : {
     324             :   // Let's continue only if we have some listeners.
     325           0 :   if (!HasListeners()) {
     326           0 :     return;
     327             :   }
     328             : 
     329             :   RefPtr<WebSocketClosedRunnable> runnable =
     330             :     new WebSocketClosedRunnable(aWebSocketSerialID, aInnerWindowID,
     331           0 :                                 aWasClean, aCode, aReason);
     332             :   DebugOnly<nsresult> rv = aTarget
     333           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     334           0 :     : NS_DispatchToMainThread(runnable);
     335           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     336             : }
     337             : 
     338             : void
     339           0 : WebSocketEventService::FrameReceived(uint32_t aWebSocketSerialID,
     340             :                                      uint64_t aInnerWindowID,
     341             :                                      already_AddRefed<WebSocketFrame> aFrame,
     342             :                                      nsIEventTarget* aTarget)
     343             : {
     344           0 :   RefPtr<WebSocketFrame> frame(Move(aFrame));
     345           0 :   MOZ_ASSERT(frame);
     346             : 
     347             :   // Let's continue only if we have some listeners.
     348           0 :   if (!HasListeners()) {
     349           0 :     return;
     350             :   }
     351             : 
     352             :   RefPtr<WebSocketFrameRunnable> runnable =
     353             :     new WebSocketFrameRunnable(aWebSocketSerialID, aInnerWindowID,
     354           0 :                                frame.forget(), false /* frameSent */);
     355             :   DebugOnly<nsresult> rv = aTarget
     356           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     357           0 :     : NS_DispatchToMainThread(runnable);
     358           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     359             : }
     360             : 
     361             : void
     362           0 : WebSocketEventService::FrameSent(uint32_t aWebSocketSerialID,
     363             :                                  uint64_t aInnerWindowID,
     364             :                                  already_AddRefed<WebSocketFrame> aFrame,
     365             :                                  nsIEventTarget* aTarget)
     366             : {
     367           0 :   RefPtr<WebSocketFrame> frame(Move(aFrame));
     368           0 :   MOZ_ASSERT(frame);
     369             : 
     370             :   // Let's continue only if we have some listeners.
     371           0 :   if (!HasListeners()) {
     372           0 :     return;
     373             :   }
     374             : 
     375             :   RefPtr<WebSocketFrameRunnable> runnable =
     376             :     new WebSocketFrameRunnable(aWebSocketSerialID, aInnerWindowID,
     377           0 :                                frame.forget(), true /* frameSent */);
     378             : 
     379             :   DebugOnly<nsresult> rv = aTarget
     380           0 :     ? aTarget->Dispatch(runnable, NS_DISPATCH_NORMAL)
     381           0 :     : NS_DispatchToMainThread(runnable);
     382           0 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed");
     383             : }
     384             : 
     385             : NS_IMETHODIMP
     386           0 : WebSocketEventService::AddListener(uint64_t aInnerWindowID,
     387             :                                    nsIWebSocketEventListener* aListener)
     388             : {
     389           0 :   MOZ_ASSERT(NS_IsMainThread());
     390             : 
     391           0 :   if (!aListener) {
     392           0 :     return NS_ERROR_FAILURE;
     393             :   }
     394             : 
     395           0 :   ++mCountListeners;
     396             : 
     397           0 :   WindowListener* listener = mWindows.Get(aInnerWindowID);
     398           0 :   if (!listener) {
     399           0 :     listener = new WindowListener();
     400             : 
     401           0 :     if (IsChildProcess()) {
     402             :       PWebSocketEventListenerChild* actor =
     403           0 :         gNeckoChild->SendPWebSocketEventListenerConstructor(aInnerWindowID);
     404             : 
     405           0 :       listener->mActor = static_cast<WebSocketEventListenerChild*>(actor);
     406           0 :       MOZ_ASSERT(listener->mActor);
     407             :     }
     408             : 
     409           0 :     mWindows.Put(aInnerWindowID, listener);
     410             :   }
     411             : 
     412           0 :   listener->mListeners.AppendElement(aListener);
     413             : 
     414           0 :   return NS_OK;
     415             : }
     416             : 
     417             : NS_IMETHODIMP
     418           0 : WebSocketEventService::RemoveListener(uint64_t aInnerWindowID,
     419             :                                       nsIWebSocketEventListener* aListener)
     420             : {
     421           0 :   MOZ_ASSERT(NS_IsMainThread());
     422             : 
     423           0 :   if (!aListener) {
     424           0 :     return NS_ERROR_FAILURE;
     425             :   }
     426             : 
     427           0 :   WindowListener* listener = mWindows.Get(aInnerWindowID);
     428           0 :   if (!listener) {
     429           0 :     return NS_ERROR_FAILURE;
     430             :   }
     431             : 
     432           0 :   if (!listener->mListeners.RemoveElement(aListener)) {
     433           0 :     return NS_ERROR_FAILURE;
     434             :   }
     435             : 
     436             :   // The last listener for this window.
     437           0 :   if (listener->mListeners.IsEmpty()) {
     438           0 :     if (IsChildProcess()) {
     439           0 :       ShutdownActorListener(listener);
     440             :     }
     441             : 
     442           0 :     mWindows.Remove(aInnerWindowID);
     443             :   }
     444             : 
     445           0 :   MOZ_ASSERT(mCountListeners);
     446           0 :   --mCountListeners;
     447             : 
     448           0 :   return NS_OK;
     449             : }
     450             : 
     451             : NS_IMETHODIMP
     452           0 : WebSocketEventService::HasListenerFor(uint64_t aInnerWindowID,
     453             :                                       bool* aResult)
     454             : {
     455           0 :   MOZ_ASSERT(NS_IsMainThread());
     456             : 
     457           0 :   *aResult = mWindows.Get(aInnerWindowID);
     458             : 
     459           0 :   return NS_OK;
     460             : }
     461             : 
     462             : NS_IMETHODIMP
     463           0 : WebSocketEventService::Observe(nsISupports* aSubject, const char* aTopic,
     464             :                                const char16_t* aData)
     465             : {
     466           0 :   MOZ_ASSERT(NS_IsMainThread());
     467             : 
     468           0 :   if (!strcmp(aTopic, "xpcom-shutdown")) {
     469           0 :     Shutdown();
     470           0 :     return NS_OK;
     471             :   }
     472             : 
     473           0 :   if (!strcmp(aTopic, "inner-window-destroyed") && HasListeners()) {
     474           0 :     nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
     475           0 :     NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
     476             : 
     477             :     uint64_t innerID;
     478           0 :     nsresult rv = wrapper->GetData(&innerID);
     479           0 :     NS_ENSURE_SUCCESS(rv, rv);
     480             : 
     481           0 :     WindowListener* listener = mWindows.Get(innerID);
     482           0 :     if (!listener) {
     483           0 :       return NS_OK;
     484             :     }
     485             : 
     486           0 :     MOZ_ASSERT(mCountListeners >= listener->mListeners.Length());
     487           0 :     mCountListeners -= listener->mListeners.Length();
     488             : 
     489           0 :     if (IsChildProcess()) {
     490           0 :       ShutdownActorListener(listener);
     491             :     }
     492             : 
     493           0 :     mWindows.Remove(innerID);
     494             :   }
     495             : 
     496             :   // This should not happen.
     497           0 :   return NS_ERROR_FAILURE;
     498             : }
     499             : 
     500             : void
     501           0 : WebSocketEventService::Shutdown()
     502             : {
     503           0 :   MOZ_ASSERT(NS_IsMainThread());
     504             : 
     505           0 :   if (gWebSocketEventService) {
     506           0 :     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     507           0 :     if (obs) {
     508           0 :       obs->RemoveObserver(gWebSocketEventService, "xpcom-shutdown");
     509           0 :       obs->RemoveObserver(gWebSocketEventService, "inner-window-destroyed");
     510             :     }
     511             : 
     512           0 :     mWindows.Clear();
     513           0 :     gWebSocketEventService = nullptr;
     514             :   }
     515           0 : }
     516             : 
     517             : bool
     518           0 : WebSocketEventService::HasListeners() const
     519             : {
     520           0 :   return !!mCountListeners;
     521             : }
     522             : 
     523             : void
     524           0 : WebSocketEventService::GetListeners(uint64_t aInnerWindowID,
     525             :                                     WebSocketEventService::WindowListeners& aListeners) const
     526             : {
     527           0 :   aListeners.Clear();
     528             : 
     529           0 :   WindowListener* listener = mWindows.Get(aInnerWindowID);
     530           0 :   if (!listener) {
     531           0 :     return;
     532             :   }
     533             : 
     534           0 :   aListeners.AppendElements(listener->mListeners);
     535             : }
     536             : 
     537             : void
     538           0 : WebSocketEventService::ShutdownActorListener(WindowListener* aListener)
     539             : {
     540           0 :   MOZ_ASSERT(aListener);
     541           0 :   MOZ_ASSERT(aListener->mActor);
     542           0 :   aListener->mActor->Close();
     543           0 :   aListener->mActor = nullptr;
     544           0 : }
     545             : 
     546             : already_AddRefed<WebSocketFrame>
     547           0 : WebSocketEventService::CreateFrameIfNeeded(bool aFinBit, bool aRsvBit1,
     548             :                                            bool aRsvBit2, bool aRsvBit3,
     549             :                                            uint8_t aOpCode, bool aMaskBit,
     550             :                                            uint32_t aMask,
     551             :                                            const nsCString& aPayload)
     552             : {
     553           0 :   if (!HasListeners()) {
     554           0 :     return nullptr;
     555             :   }
     556             : 
     557             :   return MakeAndAddRef<WebSocketFrame>(aFinBit, aRsvBit1, aRsvBit2, aRsvBit3,
     558           0 :                                        aOpCode, aMaskBit, aMask, aPayload);
     559             : }
     560             : 
     561             : already_AddRefed<WebSocketFrame>
     562           0 : WebSocketEventService::CreateFrameIfNeeded(bool aFinBit, bool aRsvBit1,
     563             :                                            bool aRsvBit2, bool aRsvBit3,
     564             :                                            uint8_t aOpCode, bool aMaskBit,
     565             :                                            uint32_t aMask, uint8_t* aPayload,
     566             :                                            uint32_t aPayloadLength)
     567             : {
     568           0 :   if (!HasListeners()) {
     569           0 :     return nullptr;
     570             :   }
     571             : 
     572           0 :   nsAutoCString payloadStr;
     573           0 :   if (NS_WARN_IF(!(payloadStr.Assign((const char*) aPayload, aPayloadLength,
     574             :                                      mozilla::fallible)))) {
     575           0 :     return nullptr;
     576             :   }
     577             : 
     578             :   return MakeAndAddRef<WebSocketFrame>(aFinBit, aRsvBit1, aRsvBit2, aRsvBit3,
     579           0 :                                        aOpCode, aMaskBit, aMask, payloadStr);
     580             : }
     581             : 
     582             : already_AddRefed<WebSocketFrame>
     583           0 : WebSocketEventService::CreateFrameIfNeeded(bool aFinBit, bool aRsvBit1,
     584             :                                            bool aRsvBit2, bool aRsvBit3,
     585             :                                            uint8_t aOpCode, bool aMaskBit,
     586             :                                            uint32_t aMask,
     587             :                                            uint8_t* aPayloadInHdr,
     588             :                                            uint32_t aPayloadInHdrLength,
     589             :                                            uint8_t* aPayload,
     590             :                                            uint32_t aPayloadLength)
     591             : {
     592           0 :   if (!HasListeners()) {
     593           0 :     return nullptr;
     594             :   }
     595             : 
     596           0 :   uint32_t payloadLength = aPayloadLength + aPayloadInHdrLength;
     597             : 
     598           0 :   nsAutoCString payload;
     599           0 :   if (NS_WARN_IF(!payload.SetLength(payloadLength, fallible))) {
     600           0 :     return nullptr;
     601             :   }
     602             : 
     603           0 :   char* payloadPtr = payload.BeginWriting();
     604           0 :   if (aPayloadInHdrLength) {
     605           0 :     memcpy(payloadPtr, aPayloadInHdr, aPayloadInHdrLength);
     606             :   }
     607             : 
     608           0 :   memcpy(payloadPtr + aPayloadInHdrLength, aPayload, aPayloadLength);
     609             : 
     610             :   return MakeAndAddRef<WebSocketFrame>(aFinBit, aRsvBit1, aRsvBit2, aRsvBit3,
     611           0 :                                        aOpCode, aMaskBit, aMask, payload);
     612             : }
     613             : 
     614             : } // net namespace
     615             : } // mozilla namespace

Generated by: LCOV version 1.13