content/base/src/nsInProcessTabChildGlobal.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
     2 /* vim: set sw=4 ts=8 et 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/. */
     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 "nsIJSRuntimeService.h"
    14 #include "nsComponentManagerUtils.h"
    15 #include "nsNetUtil.h"
    16 #include "nsScriptLoader.h"
    17 #include "nsFrameLoader.h"
    18 #include "xpcpublic.h"
    19 #include "nsIMozBrowserFrame.h"
    20 #include "nsDOMClassInfoID.h"
    21 #include "mozilla/EventDispatcher.h"
    22 #include "mozilla/dom/StructuredCloneUtils.h"
    23 #include "js/StructuredClone.h"
    25 using mozilla::dom::StructuredCloneData;
    26 using mozilla::dom::StructuredCloneClosure;
    27 using namespace mozilla;
    29 bool
    30 nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
    31                                                  const nsAString& aMessage,
    32                                                  const dom::StructuredCloneData& aData,
    33                                                  JS::Handle<JSObject *> aCpows,
    34                                                  nsIPrincipal* aPrincipal,
    35                                                  InfallibleTArray<nsString>* aJSONRetVal,
    36                                                  bool aIsSync)
    37 {
    38   nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
    39   asyncMessages.SwapElements(mASyncMessages);
    40   uint32_t len = asyncMessages.Length();
    41   for (uint32_t i = 0; i < len; ++i) {
    42     nsCOMPtr<nsIRunnable> async = asyncMessages[i];
    43     async->Run();
    44   }
    45   if (mChromeMessageManager) {
    46     SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
    47     nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
    48     mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aPrincipal,
    49                        aJSONRetVal);
    50   }
    51   return true;
    52 }
    54 class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
    55                                public nsRunnable
    56 {
    57 public:
    58   nsAsyncMessageToParent(JSContext* aCx,
    59                          nsInProcessTabChildGlobal* aTabChild,
    60                          const nsAString& aMessage,
    61                          const StructuredCloneData& aData,
    62                          JS::Handle<JSObject *> aCpows,
    63                          nsIPrincipal* aPrincipal)
    64     : nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal),
    65       mTabChild(aTabChild), mRun(false)
    66   {
    67   }
    69   NS_IMETHOD Run()
    70   {
    71     if (mRun) {
    72       return NS_OK;
    73     }
    75     mRun = true;
    76     mTabChild->mASyncMessages.RemoveElement(this);
    77     ReceiveMessage(mTabChild->mOwner, mTabChild->mChromeMessageManager);
    78     return NS_OK;
    79   }
    80   nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
    81   // True if this runnable has already been called. This can happen if DoSendSyncMessage
    82   // is called while waiting for an asynchronous message send.
    83   bool mRun;
    84 };
    86 bool
    87 nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
    88                                               const nsAString& aMessage,
    89                                               const StructuredCloneData& aData,
    90                                               JS::Handle<JSObject *> aCpows,
    91                                               nsIPrincipal* aPrincipal)
    92 {
    93   nsCOMPtr<nsIRunnable> ev =
    94     new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal);
    95   mASyncMessages.AppendElement(ev);
    96   NS_DispatchToCurrentThread(ev);
    97   return true;
    98 }
   100 nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
   101                                                      nsIContent* aOwner,
   102                                                      nsFrameMessageManager* aChrome)
   103 : mDocShell(aShell), mInitialized(false), mLoadingScript(false),
   104   mOwner(aOwner), mChromeMessageManager(aChrome)
   105 {
   107   // If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
   108   // have to tweak our PreHandleEvent implementation.
   109   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
   110   if (browserFrame) {
   111     mIsBrowserOrAppFrame = browserFrame->GetReallyIsBrowserOrApp();
   112   }
   113   else {
   114     mIsBrowserOrAppFrame = false;
   115   }
   116 }
   118 nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
   119 {
   120 }
   122 /* [notxpcom] boolean markForCC (); */
   123 // This method isn't automatically forwarded safely because it's notxpcom, so
   124 // the IDL binding doesn't know what value to return.
   125 NS_IMETHODIMP_(bool)
   126 nsInProcessTabChildGlobal::MarkForCC()
   127 {
   128   return mMessageManager ? mMessageManager->MarkForCC() : false;
   129 }
   131 nsresult
   132 nsInProcessTabChildGlobal::Init()
   133 {
   134 #ifdef DEBUG
   135   nsresult rv =
   136 #endif
   137   InitTabChildGlobal();
   138   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
   139                    "Couldn't initialize nsInProcessTabChildGlobal");
   140   mMessageManager = new nsFrameMessageManager(this,
   141                                               nullptr,
   142                                               dom::ipc::MM_CHILD);
   143   return NS_OK;
   144 }
   146 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal,
   147                                    DOMEventTargetHelper,
   148                                    mMessageManager,
   149                                    mGlobal)
   151 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
   152   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
   153   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
   154   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
   155   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
   156   NS_INTERFACE_MAP_ENTRY(nsIInProcessContentFrameMessageManager)
   157   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   158   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   159   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   160   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
   161 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
   163 NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
   164 NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
   166 NS_IMETHODIMP
   167 nsInProcessTabChildGlobal::GetContent(nsIDOMWindow** aContent)
   168 {
   169   *aContent = nullptr;
   170   nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
   171   window.swap(*aContent);
   172   return NS_OK;
   173 }
   175 NS_IMETHODIMP
   176 nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
   177 {
   178   NS_IF_ADDREF(*aDocShell = mDocShell);
   179   return NS_OK;
   180 }
   182 NS_IMETHODIMP
   183 nsInProcessTabChildGlobal::Btoa(const nsAString& aBinaryData,
   184                             nsAString& aAsciiBase64String)
   185 {
   186   return nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
   187 }
   189 NS_IMETHODIMP
   190 nsInProcessTabChildGlobal::Atob(const nsAString& aAsciiString,
   191                             nsAString& aBinaryData)
   192 {
   193   return nsContentUtils::Atob(aAsciiString, aBinaryData);
   194 }
   197 NS_IMETHODIMP
   198 nsInProcessTabChildGlobal::PrivateNoteIntentionalCrash()
   199 {
   200     return NS_ERROR_NOT_IMPLEMENTED;
   201 }
   203 void
   204 nsInProcessTabChildGlobal::Disconnect()
   205 {
   206   // Let the frame scripts know the child is being closed. We do any other
   207   // cleanup after the event has been fired. See DelayedDisconnect
   208   nsContentUtils::AddScriptRunner(
   209      NS_NewRunnableMethod(this, &nsInProcessTabChildGlobal::DelayedDisconnect)
   210   );
   211 }
   213 void
   214 nsInProcessTabChildGlobal::DelayedDisconnect()
   215 {
   216   // Don't let the event escape
   217   mOwner = nullptr;
   219   // Fire the "unload" event
   220   DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
   222   // Continue with the Disconnect cleanup
   223   nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(mDocShell);
   224   if (win) {
   225     MOZ_ASSERT(win->IsOuterWindow());
   226     win->SetChromeEventHandler(win->GetChromeEventHandler());
   227   }
   228   mDocShell = nullptr;
   229   mChromeMessageManager = nullptr;
   230   if (mMessageManager) {
   231     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
   232     mMessageManager = nullptr;
   233   }
   234   if (mListenerManager) {
   235     mListenerManager->Disconnect();
   236   }
   237 }
   239 NS_IMETHODIMP_(nsIContent *)
   240 nsInProcessTabChildGlobal::GetOwnerContent()
   241 {
   242   return mOwner;
   243 }
   245 nsresult
   246 nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor)
   247 {
   248   aVisitor.mCanHandle = true;
   250   if (mIsBrowserOrAppFrame &&
   251       (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
   252     if (mOwner) {
   253       nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();
   254       if (innerWindow) {
   255         aVisitor.mParentTarget = innerWindow->GetParentTarget();
   256       }
   257     }
   258   } else {
   259     aVisitor.mParentTarget = mOwner;
   260   }
   262 #ifdef DEBUG
   263   if (mOwner) {
   264     nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
   265     nsRefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
   266     if (fl) {
   267       NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
   268                    "Wrong event target!");
   269       NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
   270                    "Wrong message manager!");
   271     }
   272   }
   273 #endif
   275   return NS_OK;
   276 }
   278 nsresult
   279 nsInProcessTabChildGlobal::InitTabChildGlobal()
   280 {
   281   nsAutoCString id;
   282   id.AssignLiteral("inProcessTabChildGlobal");
   283   nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();
   284   if (uri) {
   285     nsAutoCString u;
   286     uri->GetSpec(u);
   287     id.AppendLiteral("?ownedBy=");
   288     id.Append(u);
   289   }
   290   nsISupports* scopeSupports = NS_ISUPPORTS_CAST(EventTarget*, this);
   291   NS_ENSURE_STATE(InitTabChildGlobalInternal(scopeSupports, id));
   292   return NS_OK;
   293 }
   295 class nsAsyncScriptLoad : public nsRunnable
   296 {
   297 public:
   298     nsAsyncScriptLoad(nsInProcessTabChildGlobal* aTabChild, const nsAString& aURL,
   299                       bool aRunInGlobalScope)
   300       : mTabChild(aTabChild), mURL(aURL), mRunInGlobalScope(aRunInGlobalScope) {}
   302   NS_IMETHOD Run()
   303   {
   304     mTabChild->LoadFrameScript(mURL, mRunInGlobalScope);
   305     return NS_OK;
   306   }
   307   nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
   308   nsString mURL;
   309   bool mRunInGlobalScope;
   310 };
   312 void
   313 nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope)
   314 {
   315   if (!nsContentUtils::IsSafeToRunScript()) {
   316     nsContentUtils::AddScriptRunner(new nsAsyncScriptLoad(this, aURL, aRunInGlobalScope));
   317     return;
   318   }
   319   if (!mInitialized) {
   320     mInitialized = true;
   321     Init();
   322   }
   323   bool tmp = mLoadingScript;
   324   mLoadingScript = true;
   325   LoadFrameScriptInternal(aURL, aRunInGlobalScope);
   326   mLoadingScript = tmp;
   327 }

mercurial