LCOV - code coverage report
Current view: top level - dom/base - nsInProcessTabChildGlobal.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 109 169 64.5 %
Date: 2017-07-14 16:53:18 Functions: 19 32 59.4 %
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 "nsInProcessTabChildGlobal.h"
       8             : #include "nsContentUtils.h"
       9             : #include "nsIScriptSecurityManager.h"
      10             : #include "nsIInterfaceRequestorUtils.h"
      11             : #include "nsIComponentManager.h"
      12             : #include "nsIServiceManager.h"
      13             : #include "nsComponentManagerUtils.h"
      14             : #include "nsFrameLoader.h"
      15             : #include "xpcpublic.h"
      16             : #include "nsIMozBrowserFrame.h"
      17             : #include "nsDOMClassInfoID.h"
      18             : #include "mozilla/EventDispatcher.h"
      19             : #include "mozilla/dom/SameProcessMessageQueue.h"
      20             : #include "mozilla/dom/ScriptLoader.h"
      21             : 
      22             : using namespace mozilla;
      23             : using namespace mozilla::dom;
      24             : using namespace mozilla::dom::ipc;
      25             : 
      26             : bool
      27           0 : nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
      28             :                                                  const nsAString& aMessage,
      29             :                                                  StructuredCloneData& aData,
      30             :                                                  JS::Handle<JSObject *> aCpows,
      31             :                                                  nsIPrincipal* aPrincipal,
      32             :                                                  nsTArray<StructuredCloneData>* aRetVal,
      33             :                                                  bool aIsSync)
      34             : {
      35           0 :   SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
      36           0 :   queue->Flush();
      37             : 
      38           0 :   if (mChromeMessageManager) {
      39           0 :     SameProcessCpowHolder cpows(JS::RootingContext::get(aCx), aCpows);
      40           0 :     RefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
      41           0 :     nsCOMPtr<nsIFrameLoader> fl = GetFrameLoader();
      42           0 :     mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal,
      43           0 :                        aRetVal);
      44             :   }
      45           0 :   return true;
      46             : }
      47             : 
      48           0 : class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
      49             :                                public SameProcessMessageQueue::Runnable
      50             : {
      51             : public:
      52           0 :   nsAsyncMessageToParent(JS::RootingContext* aRootingCx,
      53             :                          JS::Handle<JSObject*> aCpows,
      54             :                          nsInProcessTabChildGlobal* aTabChild)
      55           0 :     : nsSameProcessAsyncMessageBase(aRootingCx, aCpows)
      56           0 :     , mTabChild(aTabChild)
      57           0 :   { }
      58             : 
      59           0 :   virtual nsresult HandleMessage() override
      60             :   {
      61           0 :     nsCOMPtr<nsIFrameLoader> fl = mTabChild->GetFrameLoader();
      62           0 :     ReceiveMessage(mTabChild->mOwner, fl, mTabChild->mChromeMessageManager);
      63           0 :     return NS_OK;
      64             :   }
      65             :   RefPtr<nsInProcessTabChildGlobal> mTabChild;
      66             : };
      67             : 
      68             : nsresult
      69           0 : nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
      70             :                                               const nsAString& aMessage,
      71             :                                               StructuredCloneData& aData,
      72             :                                               JS::Handle<JSObject *> aCpows,
      73             :                                               nsIPrincipal* aPrincipal)
      74             : {
      75           0 :   SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
      76           0 :   JS::RootingContext* rcx = JS::RootingContext::get(aCx);
      77             :   RefPtr<nsAsyncMessageToParent> ev =
      78           0 :     new nsAsyncMessageToParent(rcx, aCpows, this);
      79             : 
      80           0 :   nsresult rv = ev->Init(aMessage, aData, aPrincipal);
      81           0 :   if (NS_FAILED(rv)) {
      82           0 :     return rv;
      83             :   }
      84             : 
      85           0 :   queue->Push(ev);
      86           0 :   return NS_OK;
      87             : }
      88             : 
      89           1 : nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
      90             :                                                      nsIContent* aOwner,
      91           1 :                                                      nsFrameMessageManager* aChrome)
      92             : : mDocShell(aShell), mInitialized(false), mLoadingScript(false),
      93             :   mPreventEventsEscaping(false),
      94           1 :   mOwner(aOwner), mChromeMessageManager(aChrome)
      95             : {
      96           1 :   SetIsNotDOMBinding();
      97           1 :   mozilla::HoldJSObjects(this);
      98             : 
      99             :   // If owner corresponds to an <iframe mozbrowser>, we'll have to tweak our
     100             :   // GetEventTargetParent implementation.
     101           2 :   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
     102           1 :   if (browserFrame) {
     103           0 :     mIsBrowserFrame = browserFrame->GetReallyIsBrowser();
     104             :   }
     105             :   else {
     106           1 :     mIsBrowserFrame = false;
     107             :   }
     108           1 : }
     109             : 
     110           0 : nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
     111             : {
     112           0 :   mAnonymousGlobalScopes.Clear();
     113           0 :   mozilla::DropJSObjects(this);
     114           0 : }
     115             : 
     116             : // This method isn't automatically forwarded safely because it's notxpcom, so
     117             : // the IDL binding doesn't know what value to return.
     118             : NS_IMETHODIMP_(bool)
     119           0 : nsInProcessTabChildGlobal::MarkForCC()
     120             : {
     121           0 :   MarkScopesForCC();
     122           0 :   return mMessageManager ? mMessageManager->MarkForCC() : false;
     123             : }
     124             : 
     125             : nsresult
     126           1 : nsInProcessTabChildGlobal::Init()
     127             : {
     128             : #ifdef DEBUG
     129             :   nsresult rv =
     130             : #endif
     131           1 :   InitTabChildGlobal();
     132           1 :   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
     133             :                        "Couldn't initialize nsInProcessTabChildGlobal");
     134             :   mMessageManager = new nsFrameMessageManager(this,
     135             :                                               nullptr,
     136           1 :                                               dom::ipc::MM_CHILD);
     137           1 :   return NS_OK;
     138             : }
     139             : 
     140             : NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
     141             : 
     142             : 
     143           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
     144             :                                                   DOMEventTargetHelper)
     145           0 :    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
     146           0 :    tmp->TraverseHostObjectURIs(cb);
     147           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     148             : 
     149           1 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
     150             :                                                DOMEventTargetHelper)
     151           1 :   tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
     152           1 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     153             : 
     154           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
     155             :                                                 DOMEventTargetHelper)
     156           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
     157           0 :   tmp->nsMessageManagerScriptExecutor::Unlink();
     158           0 :   tmp->UnlinkHostObjectURIs();
     159           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     160             : 
     161         300 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
     162         296 :   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
     163         295 :   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
     164         295 :   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
     165         295 :   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
     166         294 :   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
     167         293 :   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
     168         293 :   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
     169          56 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     170          56 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
     171          55 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
     172             : 
     173         471 : NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
     174         464 : NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
     175             : 
     176             : void
     177           2 : nsInProcessTabChildGlobal::CacheFrameLoader(nsIFrameLoader* aFrameLoader)
     178             : {
     179           2 :   mFrameLoader = aFrameLoader;
     180           2 : }
     181             : 
     182             : NS_IMETHODIMP
     183           1 : nsInProcessTabChildGlobal::GetContent(mozIDOMWindowProxy** aContent)
     184             : {
     185           1 :   *aContent = nullptr;
     186           1 :   if (!mDocShell) {
     187           0 :     return NS_OK;
     188             :   }
     189             : 
     190           2 :   nsCOMPtr<nsPIDOMWindowOuter> window = mDocShell->GetWindow();
     191           1 :   window.forget(aContent);
     192           1 :   return NS_OK;
     193             : }
     194             : 
     195             : NS_IMETHODIMP
     196           1 : nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
     197             : {
     198           1 :   NS_IF_ADDREF(*aDocShell = mDocShell);
     199           1 :   return NS_OK;
     200             : }
     201             : 
     202             : void
     203           1 : nsInProcessTabChildGlobal::FireUnloadEvent()
     204             : {
     205             :   // We're called from nsDocument::MaybeInitializeFinalizeFrameLoaders, so it
     206             :   // should be safe to run script.
     207           1 :   MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     208             : 
     209             :   // Don't let the unload event propagate to chrome event handlers.
     210           1 :   mPreventEventsEscaping = true;
     211           1 :   DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
     212             : 
     213             :   // Allow events fired during docshell destruction (pagehide, unload) to
     214             :   // propagate to the <browser> element since chrome code depends on this.
     215           1 :   mPreventEventsEscaping = false;
     216           1 : }
     217             : 
     218             : void
     219           1 : nsInProcessTabChildGlobal::DisconnectEventListeners()
     220             : {
     221           1 :   if (mDocShell) {
     222           2 :     if (nsCOMPtr<nsPIDOMWindowOuter> win = mDocShell->GetWindow()) {
     223           0 :       MOZ_ASSERT(win->IsOuterWindow());
     224           0 :       win->SetChromeEventHandler(win->GetChromeEventHandler());
     225             :     }
     226             :   }
     227           1 :   if (mListenerManager) {
     228           1 :     mListenerManager->Disconnect();
     229             :   }
     230             : 
     231           1 :   mDocShell = nullptr;
     232           1 : }
     233             : 
     234             : void
     235           1 : nsInProcessTabChildGlobal::Disconnect()
     236             : {
     237           1 :   mChromeMessageManager = nullptr;
     238           1 :   mOwner = nullptr;
     239           1 :   if (mMessageManager) {
     240           1 :     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
     241           1 :     mMessageManager = nullptr;
     242             :   }
     243           1 : }
     244             : 
     245             : NS_IMETHODIMP_(nsIContent *)
     246           0 : nsInProcessTabChildGlobal::GetOwnerContent()
     247             : {
     248           0 :   return mOwner;
     249             : }
     250             : 
     251             : nsresult
     252           6 : nsInProcessTabChildGlobal::GetEventTargetParent(EventChainPreVisitor& aVisitor)
     253             : {
     254           6 :   aVisitor.mForceContentDispatch = true;
     255           6 :   aVisitor.mCanHandle = true;
     256             : 
     257             : #ifdef DEBUG
     258           6 :   if (mOwner) {
     259          12 :     nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
     260          12 :     RefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
     261           6 :     if (fl) {
     262           2 :       NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
     263             :                    "Wrong event target!");
     264           2 :       NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
     265             :                    "Wrong message manager!");
     266             :     }
     267             :   }
     268             : #endif
     269             : 
     270           6 :   if (mPreventEventsEscaping) {
     271           1 :     aVisitor.mParentTarget = nullptr;
     272           1 :     return NS_OK;
     273             :   }
     274             : 
     275           5 :   if (mIsBrowserFrame &&
     276           0 :       (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
     277           0 :     if (mOwner) {
     278           0 :       if (nsPIDOMWindowInner* innerWindow = mOwner->OwnerDoc()->GetInnerWindow()) {
     279           0 :         aVisitor.mParentTarget = innerWindow->GetParentTarget();
     280             :       }
     281             :     }
     282             :   } else {
     283           5 :     aVisitor.mParentTarget = mOwner;
     284             :   }
     285             : 
     286           5 :   return NS_OK;
     287             : }
     288             : 
     289             : nsresult
     290           1 : nsInProcessTabChildGlobal::InitTabChildGlobal()
     291             : {
     292             :   // If you change this, please change GetCompartmentName() in XPCJSContext.cpp
     293             :   // accordingly.
     294           2 :   nsAutoCString id;
     295           1 :   id.AssignLiteral("inProcessTabChildGlobal");
     296           1 :   nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();
     297           1 :   if (uri) {
     298           2 :     nsAutoCString u;
     299           1 :     nsresult rv = uri->GetSpec(u);
     300           1 :     NS_ENSURE_SUCCESS(rv, rv);
     301           1 :     id.AppendLiteral("?ownedBy=");
     302           1 :     id.Append(u);
     303             :   }
     304           1 :   nsISupports* scopeSupports = NS_ISUPPORTS_CAST(EventTarget*, this);
     305           1 :   NS_ENSURE_STATE(InitChildGlobalInternal(scopeSupports, id));
     306           1 :   return NS_OK;
     307             : }
     308             : 
     309          18 : class nsAsyncScriptLoad : public Runnable
     310             : {
     311             : public:
     312           6 :   nsAsyncScriptLoad(nsInProcessTabChildGlobal* aTabChild,
     313             :                     const nsAString& aURL,
     314             :                     bool aRunInGlobalScope)
     315           6 :     : mozilla::Runnable("nsAsyncScriptLoad")
     316             :     , mTabChild(aTabChild)
     317             :     , mURL(aURL)
     318           6 :     , mRunInGlobalScope(aRunInGlobalScope)
     319             :   {
     320           6 :   }
     321             : 
     322           6 :   NS_IMETHOD Run() override
     323             :   {
     324           6 :     mTabChild->LoadFrameScript(mURL, mRunInGlobalScope);
     325           6 :     return NS_OK;
     326             :   }
     327             :   RefPtr<nsInProcessTabChildGlobal> mTabChild;
     328             :   nsString mURL;
     329             :   bool mRunInGlobalScope;
     330             : };
     331             : 
     332             : void
     333          12 : nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
     334             : {
     335          12 :   if (!nsContentUtils::IsSafeToRunScript()) {
     336           6 :     nsContentUtils::AddScriptRunner(new nsAsyncScriptLoad(this, aURL, aRunInGlobalScope));
     337           6 :     return;
     338             :   }
     339           6 :   if (!mInitialized) {
     340           1 :     mInitialized = true;
     341           1 :     Init();
     342             :   }
     343           6 :   bool tmp = mLoadingScript;
     344           6 :   mLoadingScript = true;
     345           6 :   LoadScriptInternal(aURL, aRunInGlobalScope);
     346           6 :   mLoadingScript = tmp;
     347             : }
     348             : 
     349             : already_AddRefed<nsIFrameLoader>
     350           0 : nsInProcessTabChildGlobal::GetFrameLoader()
     351             : {
     352           0 :   nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
     353           0 :   nsCOMPtr<nsIFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
     354           0 :   if (!fl) {
     355           0 :     fl = mFrameLoader;
     356             :   }
     357           0 :   return fl.forget();
     358             : }

Generated by: LCOV version 1.13