Bug 1516240 - Part 2: Allow serializing BrowsingContext over IPC, r=farre
authorNika Layzell <nika@thelayzells.com>
Wed, 13 Feb 2019 21:02:53 +0000
changeset 459058 e4bc2ad58acf
parent 459057 62e70b24ecb8
child 459059 324d25d3f933
push id111913
push usershindli@mozilla.com
push dateThu, 14 Feb 2019 05:01:59 +0000
treeherdermozilla-inbound@a0752d7e8073 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1516240
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1516240 - Part 2: Allow serializing BrowsingContext over IPC, r=farre This patch takes the approach of taking a reference, so that we can land it into the tree more quickly & fix issues we have. This isn't a final solution by any means, we should also do something along the lines of the StableState approach, but it should be sufficient for now. Depends on D19177 Differential Revision: https://phabricator.services.mozilla.com/D19178
docshell/base/BrowsingContext.cpp
docshell/base/BrowsingContext.h
dom/ipc/WindowGlobalParent.h
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -510,9 +510,51 @@ already_AddRefed<BrowsingContext> Browsi
   RefPtr<BrowsingContext> bc;
   if (childDS) {
     childDS->GetBrowsingContext(getter_AddRefs(bc));
   }
   return bc.forget();
 }
 
 }  // namespace dom
+
+namespace ipc {
+
+void IPDLParamTraits<dom::BrowsingContext>::Write(
+    IPC::Message* aMsg, IProtocol* aActor, dom::BrowsingContext* aParam) {
+  uint64_t id = aParam ? aParam->Id() : 0;
+  WriteIPDLParam(aMsg, aActor, id);
+
+  // If his is an in-process send. We want to make sure that our BrowsingContext
+  // object lives long enough to make it to the other side, so we take an extra
+  // reference. This reference is freed in ::Read().
+  if (!aActor->GetIPCChannel()->IsCrossProcess()) {
+    NS_IF_ADDREF(aParam);
+  }
+}
+
+bool IPDLParamTraits<dom::BrowsingContext>::Read(
+    const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
+    RefPtr<dom::BrowsingContext>* aResult) {
+  uint64_t id = 0;
+  if (!ReadIPDLParam(aMsg, aIter, aActor, &id)) {
+    return false;
+  }
+
+  if (id == 0) {
+    aResult = nullptr;
+    return true;
+  }
+
+  *aResult = dom::BrowsingContext::Get(id);
+  MOZ_ASSERT(aResult, "Deserialized absent BrowsingContext!");
+
+  // If this is an in-process actor, free the reference taken in ::Write().
+  if (!aActor->GetIPCChannel()->IsCrossProcess()) {
+    dom::BrowsingContext* bc = *aResult;
+    NS_IF_RELEASE(bc);
+  }
+
+  return aResult != nullptr;
+}
+
+}  // namespace ipc
 }  // namespace mozilla
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -15,23 +15,35 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocShell.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 
 class nsGlobalWindowOuter;
 class nsOuterWindowProxy;
+class PickleIterator;
+
+namespace IPC {
+class Message;
+}  // namespace IPC
 
 namespace mozilla {
 
 class ErrorResult;
 class LogModule;
 class OOMReporter;
 
+namespace ipc {
+class IProtocol;
+
+template <typename T>
+struct IPDLParamTraits;
+}  // namespace ipc
+
 namespace dom {
 
 class BrowsingContextGroup;
 class ContentParent;
 template <typename>
 struct Nullable;
 template <typename T>
 class Sequence;
@@ -249,11 +261,22 @@ class BrowsingContext : public nsWrapper
  * lives in this process, and a same-process WindowProxy should be used (see
  * nsGlobalWindowOuter). This should only be called by bindings code, ToJSValue
  * is the right API to get a WindowProxy for a BrowsingContext.
  */
 extern bool GetRemoteOuterWindowProxy(JSContext* aCx, BrowsingContext* aContext,
                                       JS::MutableHandle<JSObject*> aRetVal);
 
 }  // namespace dom
+
+// Allow sending BrowsingContext objects over IPC.
+namespace ipc {
+template <>
+struct IPDLParamTraits<dom::BrowsingContext> {
+  static void Write(IPC::Message* aMsg, IProtocol* aActor,
+                    dom::BrowsingContext* aParam);
+  static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
+                   IProtocol* aActor, RefPtr<dom::BrowsingContext>* aResult);
+};
+}  // namespace ipc
 }  // namespace mozilla
 
 #endif  // !defined(mozilla_dom_BrowsingContext_h)
--- a/dom/ipc/WindowGlobalParent.h
+++ b/dom/ipc/WindowGlobalParent.h
@@ -17,16 +17,17 @@ class nsIURI;
 class nsFrameLoader;
 
 namespace mozilla {
 namespace dom {
 
 class CanonicalBrowsingContext;
 class WindowGlobalChild;
 class JSWindowActorParent;
+class TabParent;
 
 /**
  * A handle in the parent process to a specific nsGlobalWindowInner object.
  */
 class WindowGlobalParent final : public nsISupports,
                                  public nsWrapperCache,
                                  public PWindowGlobalParent {
   friend class PWindowGlobalParent;