LCOV - code coverage report
Current view: top level - netwerk/protocol/http - HttpBackgroundChannelChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 98 193 50.8 %
Date: 2017-07-14 16:53:18 Functions: 20 31 64.5 %
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 sw=2 ts=8 et tw=80 : */
       3             : 
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : // HttpLog.h should generally be included first
       9             : #include "HttpLog.h"
      10             : 
      11             : #include "HttpBackgroundChannelChild.h"
      12             : 
      13             : #include "HttpChannelChild.h"
      14             : #include "mozilla/ipc/BackgroundChild.h"
      15             : #include "mozilla/ipc/PBackgroundChild.h"
      16             : #include "mozilla/IntegerPrintfMacros.h"
      17             : #include "mozilla/Unused.h"
      18             : #include "nsIIPCBackgroundChildCreateCallback.h"
      19             : #include "nsSocketTransportService2.h"
      20             : 
      21             : using mozilla::ipc::BackgroundChild;
      22             : using mozilla::ipc::IPCResult;
      23             : 
      24             : namespace mozilla {
      25             : namespace net {
      26             : 
      27             : // Callbacks for PBackgroundChild creation
      28             : class BackgroundChannelCreateCallback final
      29             :   : public nsIIPCBackgroundChildCreateCallback
      30             : {
      31             : public:
      32             :   NS_DECL_ISUPPORTS
      33             :   NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
      34             : 
      35           3 :   explicit BackgroundChannelCreateCallback(HttpBackgroundChannelChild* aBgChild)
      36           3 :     : mBgChild(aBgChild)
      37             :   {
      38           3 :     MOZ_ASSERT(OnSocketThread());
      39           3 :     MOZ_ASSERT(aBgChild);
      40           3 :   }
      41             : 
      42             : private:
      43           9 :   virtual ~BackgroundChannelCreateCallback() { }
      44             : 
      45             :   RefPtr<HttpBackgroundChannelChild> mBgChild;
      46             : };
      47             : 
      48          30 : NS_IMPL_ISUPPORTS(BackgroundChannelCreateCallback,
      49             :                   nsIIPCBackgroundChildCreateCallback)
      50             : 
      51             : void
      52           3 : BackgroundChannelCreateCallback::ActorCreated(PBackgroundChild* aActor)
      53             : {
      54           3 :   MOZ_ASSERT(OnSocketThread());
      55           3 :   MOZ_ASSERT(aActor);
      56           3 :   MOZ_ASSERT(mBgChild);
      57             : 
      58           3 :   if (!mBgChild->mChannelChild) {
      59             :     // HttpChannelChild is closed during PBackground creation,
      60             :     // abort the rest of steps.
      61           0 :     return;
      62             :   }
      63             : 
      64           3 :   const uint64_t channelId = mBgChild->mChannelChild->ChannelId();
      65           3 :   if (!aActor->SendPHttpBackgroundChannelConstructor(mBgChild,
      66           3 :                                                      channelId)) {
      67           0 :     ActorFailed();
      68           0 :     return;
      69             :   }
      70             : 
      71             :   // hold extra reference for IPDL
      72           6 :   RefPtr<HttpBackgroundChannelChild> child = mBgChild;
      73           3 :   Unused << child.forget().take();
      74             : 
      75           3 :   mBgChild->mChannelChild->OnBackgroundChildReady(mBgChild);
      76             : }
      77             : 
      78             : void
      79           0 : BackgroundChannelCreateCallback::ActorFailed()
      80             : {
      81           0 :   MOZ_ASSERT(OnSocketThread());
      82           0 :   MOZ_ASSERT(mBgChild);
      83             : 
      84           0 :   mBgChild->OnBackgroundChannelCreationFailed();
      85           0 : }
      86             : 
      87             : // HttpBackgroundChannelChild
      88           3 : HttpBackgroundChannelChild::HttpBackgroundChannelChild()
      89             : {
      90           3 : }
      91             : 
      92           6 : HttpBackgroundChannelChild::~HttpBackgroundChannelChild()
      93             : {
      94           9 : }
      95             : 
      96             : nsresult
      97           3 : HttpBackgroundChannelChild::Init(HttpChannelChild* aChannelChild)
      98             : {
      99           3 :   LOG(("HttpBackgroundChannelChild::Init [this=%p httpChannel=%p channelId=%"
     100             :        PRIu64 "]\n", this, aChannelChild, aChannelChild->ChannelId()));
     101           3 :   MOZ_ASSERT(OnSocketThread());
     102           3 :   NS_ENSURE_ARG(aChannelChild);
     103             : 
     104           3 :   mChannelChild = aChannelChild;
     105             : 
     106           3 :   if (NS_WARN_IF(!CreateBackgroundChannel())) {
     107           0 :     mChannelChild = nullptr;
     108           0 :     return NS_ERROR_FAILURE;
     109             :   }
     110             : 
     111           3 :   return NS_OK;
     112             : }
     113             : 
     114             : void
     115           3 : HttpBackgroundChannelChild::OnChannelClosed()
     116             : {
     117           3 :   LOG(("HttpBackgroundChannelChild::OnChannelClosed [this=%p]\n", this));
     118           3 :   MOZ_ASSERT(OnSocketThread());
     119             : 
     120             :   // HttpChannelChild is not going to handle any incoming message.
     121           3 :   mChannelChild = nullptr;
     122           3 : }
     123             : 
     124             : void
     125           3 : HttpBackgroundChannelChild::OnStartRequestReceived()
     126             : {
     127           3 :   LOG(("HttpBackgroundChannelChild::OnStartRequestReceived [this=%p]\n", this));
     128           3 :   MOZ_ASSERT(OnSocketThread());
     129           3 :   MOZ_ASSERT(mChannelChild);
     130           3 :   MOZ_ASSERT(!mStartReceived); // Should only be called once.
     131             : 
     132           3 :   mStartReceived = true;
     133             : 
     134           6 :   nsTArray<nsCOMPtr<nsIRunnable>> runnables;
     135           3 :   runnables.SwapElements(mQueuedRunnables);
     136             : 
     137           9 :   for (auto event : runnables) {
     138             :     // Note: these runnables call Recv* methods on HttpBackgroundChannelChild
     139             :     // but not the Process* methods on HttpChannelChild.
     140           6 :     event->Run();
     141             :   }
     142             : 
     143             :   // Ensure no new message is enqueued.
     144           3 :   MOZ_ASSERT(mQueuedRunnables.IsEmpty());
     145           3 : }
     146             : 
     147             : void
     148           0 : HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed()
     149             : {
     150           0 :   LOG(("HttpBackgroundChannelChild::OnBackgroundChannelCreationFailed"
     151             :        " [this=%p]\n", this));
     152           0 :   MOZ_ASSERT(OnSocketThread());
     153             : 
     154           0 :   if (mChannelChild) {
     155           0 :     RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
     156           0 :     channelChild->OnBackgroundChildDestroyed(this);
     157             :   }
     158           0 : }
     159             : 
     160             : bool
     161           3 : HttpBackgroundChannelChild::CreateBackgroundChannel()
     162             : {
     163           3 :   LOG(("HttpBackgroundChannelChild::CreateBackgroundChannel [this=%p]\n", this));
     164           3 :   MOZ_ASSERT(OnSocketThread());
     165             : 
     166             :   RefPtr<BackgroundChannelCreateCallback> callback =
     167           6 :     new BackgroundChannelCreateCallback(this);
     168             : 
     169           6 :   return BackgroundChild::GetOrCreateForCurrentThread(callback);
     170             : }
     171             : 
     172             : bool
     173          17 : HttpBackgroundChannelChild::IsWaitingOnStartRequest()
     174             : {
     175          17 :   MOZ_ASSERT(OnSocketThread());
     176             :   // Need to wait for OnStartRequest if it is sent by
     177             :   // parent process but not received by content process.
     178          17 :   return (mStartSent && !mStartReceived);
     179             : }
     180             : 
     181             : // PHttpBackgroundChannelChild
     182             : IPCResult
     183           3 : HttpBackgroundChannelChild::RecvOnStartRequestSent()
     184             : {
     185           3 :   LOG(("HttpBackgroundChannelChild::RecvOnStartRequestSent [this=%p]\n", this));
     186           3 :   MOZ_ASSERT(OnSocketThread());
     187           3 :   MOZ_ASSERT(!mStartSent); // Should only receive this message once.
     188             : 
     189           3 :   mStartSent = true;
     190           3 :   return IPC_OK();
     191             : }
     192             : 
     193             : IPCResult
     194           6 : HttpBackgroundChannelChild::RecvOnTransportAndData(
     195             :                                                const nsresult& aChannelStatus,
     196             :                                                const nsresult& aTransportStatus,
     197             :                                                const uint64_t& aOffset,
     198             :                                                const uint32_t& aCount,
     199             :                                                const nsCString& aData)
     200             : {
     201           6 :   LOG(("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p]\n", this));
     202           6 :   MOZ_ASSERT(OnSocketThread());
     203             : 
     204           6 :   if (NS_WARN_IF(!mChannelChild)) {
     205           0 :     return IPC_OK();
     206             :   }
     207             : 
     208           6 :   if (IsWaitingOnStartRequest()) {
     209           3 :     LOG(("  > pending until OnStartRequest [offset=%" PRIu64 " count=%" PRIu32
     210             :          "]\n", aOffset, aCount));
     211             : 
     212           3 :     mQueuedRunnables.AppendElement(NewRunnableMethod<const nsresult,
     213             :                                                      const nsresult,
     214             :                                                      const uint64_t,
     215             :                                                      const uint32_t,
     216           6 :                                                      const nsCString>(
     217             :       "HttpBackgroundChannelChild::RecvOnTransportAndData",
     218             :       this,
     219             :       &HttpBackgroundChannelChild::RecvOnTransportAndData,
     220             :       aChannelStatus,
     221             :       aTransportStatus,
     222             :       aOffset,
     223             :       aCount,
     224           3 :       aData));
     225             : 
     226           3 :     return IPC_OK();
     227             :   }
     228             : 
     229           3 :   mChannelChild->ProcessOnTransportAndData(aChannelStatus,
     230             :                                            aTransportStatus,
     231             :                                            aOffset,
     232             :                                            aCount,
     233           3 :                                            aData);
     234             : 
     235           3 :   return IPC_OK();
     236             : }
     237             : 
     238             : IPCResult
     239           6 : HttpBackgroundChannelChild::RecvOnStopRequest(
     240             :                                             const nsresult& aChannelStatus,
     241             :                                             const ResourceTimingStruct& aTiming)
     242             : {
     243           6 :   LOG(("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p]\n", this));
     244           6 :   MOZ_ASSERT(OnSocketThread());
     245             : 
     246           6 :   if (NS_WARN_IF(!mChannelChild)) {
     247           0 :     return IPC_OK();
     248             :   }
     249             : 
     250           6 :   if (IsWaitingOnStartRequest()) {
     251           3 :     LOG(("  > pending until OnStartRequest [status=%" PRIx32 "]\n",
     252             :          static_cast<uint32_t>(aChannelStatus)));
     253             : 
     254           3 :     mQueuedRunnables.AppendElement(
     255           6 :       NewRunnableMethod<const nsresult, const ResourceTimingStruct>(
     256             :         "HttpBackgroundChannelChild::RecvOnStopRequest",
     257             :         this,
     258             :         &HttpBackgroundChannelChild::RecvOnStopRequest,
     259             :         aChannelStatus,
     260           3 :         aTiming));
     261             : 
     262           3 :     return IPC_OK();
     263             :   }
     264             : 
     265           3 :   mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming);
     266             : 
     267           3 :   return IPC_OK();
     268             : }
     269             : 
     270             : IPCResult
     271           0 : HttpBackgroundChannelChild::RecvOnProgress(const int64_t& aProgress,
     272             :                                            const int64_t& aProgressMax)
     273             : {
     274           0 :   LOG(("HttpBackgroundChannelChild::RecvOnProgress [this=%p progress=%"
     275             :        PRId64 " max=%" PRId64 "]\n", this, aProgress, aProgressMax));
     276           0 :   MOZ_ASSERT(OnSocketThread());
     277             : 
     278           0 :   if (NS_WARN_IF(!mChannelChild)) {
     279           0 :     return IPC_OK();
     280             :   }
     281             : 
     282           0 :   if (IsWaitingOnStartRequest()) {
     283           0 :     LOG(("  > pending until OnStartRequest [progress=%" PRId64 " max=%"
     284             :          PRId64 "]\n", aProgress, aProgressMax));
     285             : 
     286           0 :     mQueuedRunnables.AppendElement(
     287           0 :       NewRunnableMethod<const int64_t, const int64_t>(
     288             :         "HttpBackgroundChannelChild::RecvOnProgress",
     289             :         this,
     290             :         &HttpBackgroundChannelChild::RecvOnProgress,
     291             :         aProgress,
     292           0 :         aProgressMax));
     293             : 
     294           0 :     return IPC_OK();
     295             :   }
     296             : 
     297           0 :   mChannelChild->ProcessOnProgress(aProgress, aProgressMax);
     298             : 
     299           0 :   return IPC_OK();
     300             : }
     301             : 
     302             : IPCResult
     303           5 : HttpBackgroundChannelChild::RecvOnStatus(const nsresult& aStatus)
     304             : {
     305           5 :   LOG(("HttpBackgroundChannelChild::RecvOnStatus [this=%p status=%"
     306             :        PRIx32 "]\n", this, static_cast<uint32_t>(aStatus)));
     307           5 :   MOZ_ASSERT(OnSocketThread());
     308             : 
     309           5 :   if (NS_WARN_IF(!mChannelChild)) {
     310           0 :     return IPC_OK();
     311             :   }
     312             : 
     313           5 :   if (IsWaitingOnStartRequest()) {
     314           0 :     LOG(("  > pending until OnStartRequest [status=%" PRIx32 "]\n",
     315             :          static_cast<uint32_t>(aStatus)));
     316             : 
     317           0 :     mQueuedRunnables.AppendElement(NewRunnableMethod<const nsresult>(
     318             :       "HttpBackgroundChannelChild::RecvOnStatus",
     319             :       this,
     320             :       &HttpBackgroundChannelChild::RecvOnStatus,
     321           0 :       aStatus));
     322             : 
     323           0 :     return IPC_OK();
     324             :   }
     325             : 
     326           5 :   mChannelChild->ProcessOnStatus(aStatus);
     327             : 
     328           5 :   return IPC_OK();
     329             : }
     330             : 
     331             : IPCResult
     332           0 : HttpBackgroundChannelChild::RecvFlushedForDiversion()
     333             : {
     334           0 :   LOG(("HttpBackgroundChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
     335           0 :   MOZ_ASSERT(OnSocketThread());
     336             : 
     337           0 :   if (NS_WARN_IF(!mChannelChild)) {
     338           0 :     return IPC_OK();
     339             :   }
     340             : 
     341           0 :   if (IsWaitingOnStartRequest()) {
     342           0 :     LOG(("  > pending until OnStartRequest\n"));
     343             : 
     344           0 :     mQueuedRunnables.AppendElement(NewRunnableMethod(
     345             :       "HttpBackgroundChannelChild::RecvFlushedForDiversion",
     346             :       this,
     347           0 :       &HttpBackgroundChannelChild::RecvFlushedForDiversion));
     348             : 
     349           0 :     return IPC_OK();
     350             :   }
     351             : 
     352           0 :   mChannelChild->ProcessFlushedForDiversion();
     353             : 
     354           0 :   return IPC_OK();
     355             : }
     356             : 
     357             : IPCResult
     358           0 : HttpBackgroundChannelChild::RecvDivertMessages()
     359             : {
     360           0 :   LOG(("HttpBackgroundChannelChild::RecvDivertMessages [this=%p]\n", this));
     361           0 :   MOZ_ASSERT(OnSocketThread());
     362             : 
     363           0 :   if (NS_WARN_IF(!mChannelChild)) {
     364           0 :     return IPC_OK();
     365             :   }
     366             : 
     367           0 :   if (IsWaitingOnStartRequest()) {
     368           0 :     LOG(("  > pending until OnStartRequest\n"));
     369             : 
     370           0 :     mQueuedRunnables.AppendElement(
     371           0 :       NewRunnableMethod("HttpBackgroundChannelChild::RecvDivertMessages",
     372             :                         this,
     373           0 :                         &HttpBackgroundChannelChild::RecvDivertMessages));
     374             : 
     375           0 :     return IPC_OK();
     376             :   }
     377             : 
     378           0 :   mChannelChild->ProcessDivertMessages();
     379             : 
     380           0 :   return IPC_OK();
     381             : }
     382             : 
     383             : IPCResult
     384           0 : HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled()
     385             : {
     386           0 :   LOG(("HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled [this=%p]\n", this));
     387           0 :   MOZ_ASSERT(OnSocketThread());
     388             : 
     389           0 :   if (NS_WARN_IF(!mChannelChild)) {
     390           0 :     return IPC_OK();
     391             :   }
     392             : 
     393             :   // NotifyTrackingProtectionDisabled has no order dependency to OnStartRequest.
     394             :   // It this be handled as soon as possible
     395           0 :   mChannelChild->ProcessNotifyTrackingProtectionDisabled();
     396             : 
     397           0 :   return IPC_OK();
     398             : }
     399             : 
     400             : IPCResult
     401           0 : HttpBackgroundChannelChild::RecvNotifyTrackingResource()
     402             : {
     403           0 :   LOG(("HttpBackgroundChannelChild::RecvNotifyTrackingResource [this=%p]\n", this));
     404           0 :   MOZ_ASSERT(OnSocketThread());
     405             : 
     406           0 :   if (NS_WARN_IF(!mChannelChild)) {
     407           0 :     return IPC_OK();
     408             :   }
     409             : 
     410             :   // NotifyTrackingResource has no order dependency to OnStartRequest.
     411             :   // It this be handled as soon as possible
     412           0 :   mChannelChild->ProcessNotifyTrackingResource();
     413             : 
     414           0 :   return IPC_OK();
     415             : }
     416             : 
     417             : IPCResult
     418           0 : HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo(const ClassifierInfo& info)
     419             : {
     420           0 :   LOG(("HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n", this));
     421           0 :   MOZ_ASSERT(OnSocketThread());
     422             : 
     423           0 :   if (NS_WARN_IF(!mChannelChild)) {
     424           0 :     return IPC_OK();
     425             :   }
     426             : 
     427             :   // SetClassifierMatchedInfo has no order dependency to OnStartRequest.
     428             :   // It this be handled as soon as possible
     429           0 :   mChannelChild->ProcessSetClassifierMatchedInfo(info.list(), info.provider(), info.prefix());
     430             : 
     431           0 :   return IPC_OK();
     432             : }
     433             : 
     434             : void
     435           3 : HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
     436             : {
     437           3 :   LOG(("HttpBackgroundChannelChild::ActorDestroy[this=%p]\n", this));
     438             :   // This function might be called during shutdown phase, so OnSocketThread()
     439             :   // might return false even on STS thread. Use IsOnCurrentThreadInfallible()
     440             :   // to get correct information.
     441           3 :   MOZ_ASSERT(gSocketTransportService);
     442           3 :   MOZ_ASSERT(gSocketTransportService->IsOnCurrentThreadInfallible());
     443             : 
     444             :   // Ensure all IPC messages received before ActorDestroy can be
     445             :   // handled correctly. If there is any pending IPC message, destroyed
     446             :   // mChannelChild until those messages are flushed.
     447             :   // If background channel is not closed by normal IPDL actor deletion,
     448             :   // remove the HttpChannelChild reference and notify background channel
     449             :   // destroyed immediately.
     450           3 :   if (aWhy == Deletion && !mQueuedRunnables.IsEmpty()) {
     451           0 :     LOG(("  > pending until queued messages are flushed\n"));
     452           0 :     RefPtr<HttpBackgroundChannelChild> self = this;
     453           0 :     mQueuedRunnables.AppendElement(NS_NewRunnableFunction(
     454           0 :       "HttpBackgroundChannelChild::ActorDestroy", [self]() {
     455           0 :         MOZ_ASSERT(NS_IsMainThread());
     456           0 :         RefPtr<HttpChannelChild> channelChild = self->mChannelChild.forget();
     457             : 
     458           0 :         if (channelChild) {
     459           0 :           channelChild->OnBackgroundChildDestroyed(self);
     460             :         }
     461           0 :       }));
     462           0 :     return;
     463             :   }
     464             : 
     465           3 :   if (mChannelChild) {
     466           0 :     RefPtr<HttpChannelChild> channelChild = mChannelChild.forget();
     467             : 
     468           0 :     channelChild->OnBackgroundChildDestroyed(this);
     469             :   }
     470             : }
     471             : 
     472             : } // namespace net
     473             : } // namespace mozilla

Generated by: LCOV version 1.13