diff --git a/content/base/src/nsFrameMessageManager.cpp b/content/base/src/nsFrameMessageManager.cpp index 06045ea1532..15db6c0b381 100644 --- a/content/base/src/nsFrameMessageManager.cpp +++ b/content/base/src/nsFrameMessageManager.cpp @@ -154,7 +154,7 @@ struct BlobTraits { typedef mozilla::dom::BlobChild BlobType; typedef mozilla::dom::PBlobChild ProtocolType; - typedef mozilla::dom::ContentChild ConcreteContentManagerType; + typedef mozilla::dom::nsIContentChild ConcreteContentManagerType; }; template @@ -229,7 +229,7 @@ MessageManagerCallback::BuildClonedMessageDataForParent(nsIContentParent* aParen } bool -MessageManagerCallback::BuildClonedMessageDataForChild(ContentChild* aChild, +MessageManagerCallback::BuildClonedMessageDataForChild(nsIContentChild* aChild, const StructuredCloneData& aData, ClonedMessageData& aClonedData) { diff --git a/content/base/src/nsFrameMessageManager.h b/content/base/src/nsFrameMessageManager.h index e6ee16041ed..8919215f864 100644 --- a/content/base/src/nsFrameMessageManager.h +++ b/content/base/src/nsFrameMessageManager.h @@ -33,7 +33,7 @@ namespace mozilla { namespace dom { class nsIContentParent; -class ContentChild; +class nsIContentChild; class ClonedMessageData; class MessageManagerReporter; @@ -102,7 +102,7 @@ protected: bool BuildClonedMessageDataForParent(nsIContentParent* aParent, const StructuredCloneData& aData, ClonedMessageData& aClonedData); - bool BuildClonedMessageDataForChild(ContentChild* aChild, + bool BuildClonedMessageDataForChild(nsIContentChild* aChild, const StructuredCloneData& aData, ClonedMessageData& aClonedData); }; diff --git a/dom/ipc/Blob.cpp b/dom/ipc/Blob.cpp index 2f766e874b6..55a073ece5e 100644 --- a/dom/ipc/Blob.cpp +++ b/dom/ipc/Blob.cpp @@ -13,6 +13,7 @@ #include "mozilla/Monitor.h" #include "mozilla/unused.h" #include "mozilla/dom/nsIContentParent.h" +#include "mozilla/dom/nsIContentChild.h" #include "mozilla/dom/PBlobStreamChild.h" #include "mozilla/dom/PBlobStreamParent.h" #include "mozilla/dom/PFileDescriptorSetParent.h" @@ -1056,7 +1057,7 @@ RemoteBlob::GetPBlob() * BlobChild ******************************************************************************/ -BlobChild::BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob) +BlobChild::BlobChild(nsIContentChild* aManager, nsIDOMBlob* aBlob) : mBlob(aBlob) , mRemoteBlob(nullptr) , mStrongManager(aManager) @@ -1073,7 +1074,7 @@ BlobChild::BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob) mBlobIsFile = !!file; } -BlobChild::BlobChild(ContentChild* aManager, +BlobChild::BlobChild(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams) : mBlob(nullptr) , mRemoteBlob(nullptr) @@ -1105,7 +1106,7 @@ BlobChild::~BlobChild() } BlobChild* -BlobChild::Create(ContentChild* aManager, +BlobChild::Create(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams) { MOZ_ASSERT(NS_IsMainThread()); @@ -1205,6 +1206,12 @@ BlobChild::SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength) return SendResolveMystery(params); } +nsIContentChild* +BlobChild::Manager() +{ + return mStrongManager; +} + already_AddRefed BlobChild::CreateRemoteBlob(const ChildBlobConstructorParams& aParams) { diff --git a/dom/ipc/Blob.h b/dom/ipc/Blob.h index 3c766aa1619..65e534c71ad 100644 --- a/dom/ipc/Blob.h +++ b/dom/ipc/Blob.h @@ -18,7 +18,7 @@ template class nsRevocableEventPtr; namespace mozilla { namespace dom { -class ContentChild; +class nsIContentChild; class nsIContentParent; class PBlobStreamChild; class PBlobStreamParent; @@ -26,14 +26,14 @@ class PBlobStreamParent; class BlobChild MOZ_FINAL : public PBlobChild { - friend class ContentChild; + friend class nsIContentChild; class RemoteBlob; friend class RemoteBlob; nsIDOMBlob* mBlob; RemoteBlob* mRemoteBlob; - nsRefPtr mStrongManager; + nsRefPtr mStrongManager; bool mOwnsBlob; bool mBlobIsFile; @@ -41,7 +41,7 @@ class BlobChild MOZ_FINAL public: // This create function is called on the sending side. static BlobChild* - Create(ContentChild* aManager, nsIDOMBlob* aBlob) + Create(nsIContentChild* aManager, nsIDOMBlob* aBlob) { return new BlobChild(aManager, aBlob); } @@ -63,19 +63,21 @@ public: bool SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength); + nsIContentChild* Manager(); + private: // This constructor is called on the sending side. - BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob); + BlobChild(nsIContentChild* aManager, nsIDOMBlob* aBlob); // This constructor is called on the receiving side. - BlobChild(ContentChild* aManager, const ChildBlobConstructorParams& aParams); + BlobChild(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams); // Only destroyed by ContentChild. ~BlobChild(); // This create function is called on the receiving side by ContentChild. static BlobChild* - Create(ContentChild* aManager, const ChildBlobConstructorParams& aParams); + Create(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams); static already_AddRefed CreateRemoteBlob(const ChildBlobConstructorParams& aParams); diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index dc788496616..508e9a3fd96 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -18,12 +18,14 @@ #include "TabChild.h" #include "mozilla/Attributes.h" -#include "mozilla/dom/asmjscache/AsmJSCache.h" -#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h" +#include "mozilla/Preferences.h" +#include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/ExternalHelperAppChild.h" #include "mozilla/dom/PCrashReporterChild.h" -#include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/Promise.h" +#include "mozilla/dom/asmjscache/AsmJSCache.h" +#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h" +#include "mozilla/dom/nsIContentChild.h" #include "mozilla/hal_sandbox/PHalChild.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/FileDescriptorUtils.h" @@ -31,10 +33,9 @@ #include "mozilla/ipc/TestShellChild.h" #include "mozilla/layers/CompositorChild.h" #include "mozilla/layers/ImageBridgeChild.h" -#include "mozilla/layers/SharedBufferManagerChild.h" #include "mozilla/layers/PCompositorChild.h" +#include "mozilla/layers/SharedBufferManagerChild.h" #include "mozilla/net/NeckoChild.h" -#include "mozilla/Preferences.h" #if defined(MOZ_CONTENT_SANDBOX) #if defined(XP_WIN) @@ -497,6 +498,11 @@ ContentChild::~ContentChild() { } +NS_INTERFACE_MAP_BEGIN(ContentChild) + NS_INTERFACE_MAP_ENTRY(nsIContentChild) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + bool ContentChild::Init(MessageLoop* aIOLoop, base::ProcessHandle aParentHandle, @@ -900,51 +906,43 @@ ContentChild::AllocPJavaScriptChild() { MOZ_ASSERT(!ManagedPJavaScriptChild().Length()); - nsCOMPtr svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); - NS_ENSURE_TRUE(svc, nullptr); - - JSRuntime *rt; - svc->GetRuntime(&rt); - NS_ENSURE_TRUE(svc, nullptr); - - mozilla::jsipc::JavaScriptChild *child = new mozilla::jsipc::JavaScriptChild(rt); - if (!child->init()) { - delete child; - return nullptr; - } - return child; + return nsIContentChild::AllocPJavaScriptChild(); } bool -ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *child) +ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *aChild) { - static_cast(child)->decref(); - return true; + return nsIContentChild::DeallocPJavaScriptChild(aChild); } PBrowserChild* ContentChild::AllocPBrowserChild(const IPCTabContext& aContext, const uint32_t& aChromeFlags, - const uint64_t& aId, + const uint64_t& aID, const bool& aIsForApp, const bool& aIsForBrowser) { - // We'll happily accept any kind of IPCTabContext here; we don't need to - // check that it's of a certain type for security purposes, because we - // believe whatever the parent process tells us. + return nsIContentChild::AllocPBrowserChild(aContext, + aChromeFlags, + aID, + aIsForApp, + aIsForBrowser); +} - MaybeInvalidTabContext tc(aContext); - if (!tc.IsValid()) { - NS_ERROR(nsPrintfCString("Received an invalid TabContext from " - "the parent process. (%s) Crashing...", - tc.GetInvalidReason()).get()); - MOZ_CRASH("Invalid TabContext received from the parent process."); - } - - nsRefPtr child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags); - - // The ref here is released in DeallocPBrowserChild. - return child.forget().take(); +bool +ContentChild::SendPBrowserConstructor(PBrowserChild* aActor, + const IPCTabContext& aContext, + const uint32_t& aChromeFlags, + const uint64_t& aID, + const bool& aIsForApp, + const bool& aIsForBrowser) +{ + return PContentChild::SendPBrowserConstructor(aActor, + aContext, + aChromeFlags, + aID, + aIsForApp, + aIsForBrowser); } bool @@ -998,108 +996,28 @@ ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor) } bool -ContentChild::DeallocPBrowserChild(PBrowserChild* iframe) +ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe) { - TabChild* child = static_cast(iframe); - NS_RELEASE(child); - return true; + return nsIContentChild::DeallocPBrowserChild(aIframe); } PBlobChild* ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams) { - return BlobChild::Create(this, aParams); + return nsIContentChild::AllocPBlobChild(aParams); } bool ContentChild::DeallocPBlobChild(PBlobChild* aActor) { - delete aActor; - return true; + return nsIContentChild::DeallocPBlobChild(aActor); } -BlobChild* -ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob) +PBlobChild* +ContentChild::SendPBlobConstructor(PBlobChild* aActor, + const BlobConstructorParams& aParams) { - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aBlob); - - // If the blob represents a remote blob then we can simply pass its actor back - // here. - if (nsCOMPtr remoteBlob = do_QueryInterface(aBlob)) { - BlobChild* actor = - static_cast( - static_cast(remoteBlob->GetPBlob())); - MOZ_ASSERT(actor); - return actor; - } - - // All blobs shared between processes must be immutable. - nsCOMPtr mutableBlob = do_QueryInterface(aBlob); - if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) { - NS_WARNING("Failed to make blob immutable!"); - return nullptr; - } - -#ifdef DEBUG - { - // XXX This is only safe so long as all blob implementations in our tree - // inherit nsDOMFileBase. If that ever changes then this will need to - // grow a real interface or something. - const auto* blob = static_cast(aBlob); - - MOZ_ASSERT(!blob->IsSizeUnknown()); - MOZ_ASSERT(!blob->IsDateUnknown()); - } -#endif - - ParentBlobConstructorParams params; - - nsString contentType; - nsresult rv = aBlob->GetType(contentType); - NS_ENSURE_SUCCESS(rv, nullptr); - - uint64_t length; - rv = aBlob->GetSize(&length); - NS_ENSURE_SUCCESS(rv, nullptr); - - nsCOMPtr stream; - rv = aBlob->GetInternalStream(getter_AddRefs(stream)); - NS_ENSURE_SUCCESS(rv, nullptr); - - InputStreamParams inputStreamParams; - nsTArray fds; - SerializeInputStream(stream, inputStreamParams, fds); - - MOZ_ASSERT(fds.IsEmpty()); - - params.optionalInputStreamParams() = inputStreamParams; - - nsCOMPtr file = do_QueryInterface(aBlob); - if (file) { - FileBlobConstructorParams fileParams; - - rv = file->GetName(fileParams.name()); - NS_ENSURE_SUCCESS(rv, nullptr); - - rv = file->GetMozLastModifiedDate(&fileParams.modDate()); - NS_ENSURE_SUCCESS(rv, nullptr); - - fileParams.contentType() = contentType; - fileParams.length() = length; - - params.blobParams() = fileParams; - } else { - NormalBlobConstructorParams blobParams; - blobParams.contentType() = contentType; - blobParams.length() = length; - params.blobParams() = blobParams; - } - - BlobChild* actor = BlobChild::Create(this, aBlob); - NS_ENSURE_TRUE(actor, nullptr); - - return SendPBlobConstructor(actor, params) ? actor : nullptr; + return PContentChild::SendPBlobConstructor(aActor, aParams); } PCrashReporterChild* diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index e35fce91fda..259a8b547a8 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -8,6 +8,7 @@ #define mozilla_dom_ContentChild_h #include "mozilla/Attributes.h" +#include "mozilla/dom/nsIContentChild.h" #include "mozilla/dom/PContentChild.h" #include "mozilla/dom/ipc/Blob.h" #include "nsHashKeys.h" @@ -48,6 +49,7 @@ class ClonedMessageData; class PFileDescriptorSetChild; class ContentChild : public PContentChild + , public nsIContentChild { typedef mozilla::dom::ClonedMessageData ClonedMessageData; typedef mozilla::ipc::OptionalURIParams OptionalURIParams; @@ -56,8 +58,9 @@ class ContentChild : public PContentChild public: ContentChild(); virtual ~ContentChild(); - nsrefcnt AddRef() { return 1; } - nsrefcnt Release() { return 1; } + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + NS_IMETHOD_(MozExternalRefCountType) AddRef(void) { return 1; } + NS_IMETHOD_(MozExternalRefCountType) Release(void) { return 1; } struct AppInfo { @@ -299,7 +302,9 @@ public: bool IsForApp() { return mIsForApp; } bool IsForBrowser() { return mIsForBrowser; } - BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob); + virtual PBlobChild* + SendPBlobConstructor(PBlobChild* actor, + const BlobConstructorParams& params) MOZ_OVERRIDE; virtual PFileDescriptorSetChild* AllocPFileDescriptorSetChild(const FileDescriptor&) MOZ_OVERRIDE; @@ -307,6 +312,12 @@ public: virtual bool DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE; + virtual bool SendPBrowserConstructor(PBrowserChild* actor, + const IPCTabContext& context, + const uint32_t& chromeFlags, + const uint64_t& aID, + const bool& aIsForApp, + const bool& aIsForBrowser) MOZ_OVERRIDE; protected: virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor, const IPCTabContext& aContext, diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 74cc13c3f7f..7bdf6921487 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -652,7 +652,7 @@ TabChild::PreloadSlowThings() } /*static*/ already_AddRefed -TabChild::Create(ContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags) +TabChild::Create(nsIContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags) { if (sPreallocatedTab && sPreallocatedTab->mChromeFlags == aChromeFlags && @@ -674,7 +674,7 @@ TabChild::Create(ContentChild* aManager, const TabContext &aContext, uint32_t aC } -TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags) +TabChild::TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags) : TabContext(aContext) , mRemoteFrame(nullptr) , mManager(aManager) @@ -2322,7 +2322,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage, StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData); nsRefPtr mm = static_cast(mTabChildGlobal->mMessageManager.get()); - CpowIdHolder cpows(static_cast(Manager())->GetCPOWManager(), aCpows); + CpowIdHolder cpows(Manager()->GetCPOWManager(), aCpows); mm->ReceiveMessage(static_cast(mTabChildGlobal), aMessage, false, &cloneData, &cpows, aPrincipal, nullptr); } @@ -2668,14 +2668,13 @@ TabChild::DoSendBlockingMessage(JSContext* aCx, InfallibleTArray* aJSONRetVal, bool aIsSync) { - ContentChild* cc = Manager(); ClonedMessageData data; - if (!BuildClonedMessageDataForChild(cc, aData, data)) { + if (!BuildClonedMessageDataForChild(Manager(), aData, data)) { return false; } InfallibleTArray cpows; if (sCpowsEnabled) { - if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { + if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { return false; } } @@ -2695,14 +2694,13 @@ TabChild::DoSendAsyncMessage(JSContext* aCx, JS::Handle aCpows, nsIPrincipal* aPrincipal) { - ContentChild* cc = Manager(); ClonedMessageData data; - if (!BuildClonedMessageDataForChild(cc, aData, data)) { + if (!BuildClonedMessageDataForChild(Manager(), aData, data)) { return false; } InfallibleTArray cpows; if (sCpowsEnabled) { - if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { + if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { return false; } } diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index cfafd7b1947..0f9218f0536 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -250,7 +250,7 @@ public: /** Return a TabChild with the given attributes. */ static already_AddRefed - Create(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags); + Create(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags); virtual ~TabChild(); @@ -430,7 +430,7 @@ public: const nsAString& aPath, nsICachedFileDescriptorListener* aCallback); - ContentChild* Manager() { return mManager; } + nsIContentChild* Manager() { return mManager; } bool GetUpdateHitRegion() { return mUpdateHitRegion; } @@ -483,7 +483,7 @@ private: * * |aIsBrowserElement| indicates whether we're a browser (but not an app). */ - TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags); + TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags); nsresult Init(); @@ -536,7 +536,7 @@ private: nsCOMPtr mWidget; nsCOMPtr mLastURI; RenderFrameChild* mRemoteFrame; - nsRefPtr mManager; + nsRefPtr mManager; uint32_t mChromeFlags; uint64_t mLayersId; nsIntRect mOuterRect; diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 37174c89e1c..db17d1fd929 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -25,6 +25,7 @@ EXPORTS.mozilla.dom += [ 'FileDescriptorSetChild.h', 'FileDescriptorSetParent.h', 'FilePickerParent.h', + 'nsIContentChild.h', 'nsIContentParent.h', 'PermissionMessageUtils.h', 'StructuredCloneUtils.h', @@ -49,6 +50,7 @@ UNIFIED_SOURCES += [ 'FileDescriptorSetChild.cpp', 'FileDescriptorSetParent.cpp', 'FilePickerParent.cpp', + 'nsIContentChild.cpp', 'nsIContentParent.cpp', 'PermissionMessageUtils.cpp', 'PreallocatedProcessManager.cpp', diff --git a/dom/ipc/nsIContentChild.cpp b/dom/ipc/nsIContentChild.cpp new file mode 100644 index 00000000000..2ff3d56f24c --- /dev/null +++ b/dom/ipc/nsIContentChild.cpp @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIContentChild.h" + +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/PermissionMessageUtils.h" +#include "mozilla/dom/StructuredCloneUtils.h" +#include "mozilla/dom/TabChild.h" +#include "mozilla/dom/ipc/nsIRemoteBlob.h" +#include "mozilla/ipc/InputStreamUtils.h" + +#include "JavaScriptChild.h" +#include "nsDOMFile.h" +#include "nsIJSRuntimeService.h" +#include "nsPrintfCString.h" + +using namespace mozilla::ipc; +using namespace mozilla::jsipc; + +namespace mozilla { +namespace dom { + +PJavaScriptChild* +nsIContentChild::AllocPJavaScriptChild() +{ + nsCOMPtr svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); + NS_ENSURE_TRUE(svc, nullptr); + + JSRuntime *rt; + svc->GetRuntime(&rt); + NS_ENSURE_TRUE(svc, nullptr); + + nsAutoPtr child(new JavaScriptChild(rt)); + if (!child->init()) { + return nullptr; + } + return child.forget(); +} + +bool +nsIContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild) +{ + static_cast(aChild)->decref(); + return true; +} + +PBrowserChild* +nsIContentChild::AllocPBrowserChild(const IPCTabContext& aContext, + const uint32_t& aChromeFlags, + const uint64_t& aID, + const bool& aIsForApp, + const bool& aIsForBrowser) +{ + // We'll happily accept any kind of IPCTabContext here; we don't need to + // check that it's of a certain type for security purposes, because we + // believe whatever the parent process tells us. + + MaybeInvalidTabContext tc(aContext); + if (!tc.IsValid()) { + NS_ERROR(nsPrintfCString("Received an invalid TabContext from " + "the parent process. (%s) Crashing...", + tc.GetInvalidReason()).get()); + MOZ_CRASH("Invalid TabContext received from the parent process."); + } + + nsRefPtr child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags); + + // The ref here is released in DeallocPBrowserChild. + return child.forget().take(); +} + +bool +nsIContentChild::DeallocPBrowserChild(PBrowserChild* aIframe) +{ + TabChild* child = static_cast(aIframe); + NS_RELEASE(child); + return true; +} + +PBlobChild* +nsIContentChild::AllocPBlobChild(const BlobConstructorParams& aParams) +{ + return BlobChild::Create(this, aParams); +} + +bool +nsIContentChild::DeallocPBlobChild(PBlobChild* aActor) +{ + delete aActor; + return true; +} + +BlobChild* +nsIContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aBlob); + + // If the blob represents a remote blob then we can simply pass its actor back + // here. + if (nsCOMPtr remoteBlob = do_QueryInterface(aBlob)) { + BlobChild* actor = + static_cast( + static_cast(remoteBlob->GetPBlob())); + MOZ_ASSERT(actor); + if (actor->Manager() == this) { + return actor; + } + } + + // All blobs shared between processes must be immutable. + nsCOMPtr mutableBlob = do_QueryInterface(aBlob); + if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) { + NS_WARNING("Failed to make blob immutable!"); + return nullptr; + } + +#ifdef DEBUG + { + // XXX This is only safe so long as all blob implementations in our tree + // inherit nsDOMFileBase. If that ever changes then this will need to + // grow a real interface or something. + const auto* blob = static_cast(aBlob); + + MOZ_ASSERT(!blob->IsSizeUnknown()); + MOZ_ASSERT(!blob->IsDateUnknown()); + } +#endif + + ParentBlobConstructorParams params; + + nsString contentType; + nsresult rv = aBlob->GetType(contentType); + NS_ENSURE_SUCCESS(rv, nullptr); + + uint64_t length; + rv = aBlob->GetSize(&length); + NS_ENSURE_SUCCESS(rv, nullptr); + + nsCOMPtr stream; + rv = aBlob->GetInternalStream(getter_AddRefs(stream)); + NS_ENSURE_SUCCESS(rv, nullptr); + + InputStreamParams inputStreamParams; + nsTArray fds; + SerializeInputStream(stream, inputStreamParams, fds); + + MOZ_ASSERT(fds.IsEmpty()); + + params.optionalInputStreamParams() = inputStreamParams; + + nsCOMPtr file = do_QueryInterface(aBlob); + if (file) { + FileBlobConstructorParams fileParams; + + rv = file->GetName(fileParams.name()); + NS_ENSURE_SUCCESS(rv, nullptr); + + rv = file->GetMozLastModifiedDate(&fileParams.modDate()); + NS_ENSURE_SUCCESS(rv, nullptr); + + fileParams.contentType() = contentType; + fileParams.length() = length; + + params.blobParams() = fileParams; + } else { + NormalBlobConstructorParams blobParams; + blobParams.contentType() = contentType; + blobParams.length() = length; + params.blobParams() = blobParams; + } + + BlobChild* actor = BlobChild::Create(this, aBlob); + NS_ENSURE_TRUE(actor, nullptr); + + return SendPBlobConstructor(actor, params) ? actor : nullptr; +} + +bool +nsIContentChild::RecvAsyncMessage(const nsString& aMsg, + const ClonedMessageData& aData, + const InfallibleTArray& aCpows, + const IPC::Principal& aPrincipal) +{ + nsRefPtr cpm = nsFrameMessageManager::sChildProcessManager; + if (cpm) { + StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData); + CpowIdHolder cpows(GetCPOWManager(), aCpows); + cpm->ReceiveMessage(static_cast(cpm.get()), + aMsg, false, &cloneData, &cpows, aPrincipal, nullptr); + } + return true; +} + +} // dom +} // mozilla diff --git a/dom/ipc/nsIContentChild.h b/dom/ipc/nsIContentChild.h new file mode 100644 index 00000000000..5b68dde575e --- /dev/null +++ b/dom/ipc/nsIContentChild.h @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_nsIContentChild_h +#define mozilla_dom_nsIContentChild_h + +#include "mozilla/dom/ipc/Blob.h" + +#include "nsISupports.h" + +#define NS_ICONTENTCHILD_IID \ + { 0x4eed2e73, 0x94ba, 0x48a8, \ + { 0xa2, 0xd1, 0xa5, 0xed, 0x86, 0xd7, 0xbb, 0xe4 } } + +class PBrowserChild; + +namespace IPC { +class Principal; +} // IPC + +namespace mozilla { + +namespace jsipc { +class PJavaScriptChild; +class JavaScriptChild; +class CpowEntry; +} // jsipc + +namespace dom { +struct IPCTabContext; + +class nsIContentChild : public nsISupports +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID) + + BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob); + + virtual PBlobChild* + SendPBlobConstructor(PBlobChild* aActor, + const BlobConstructorParams& params) = 0; + virtual bool + SendPBrowserConstructor(PBrowserChild* aActor, + const IPCTabContext& aContext, + const uint32_t& aChromeFlags, + const uint64_t& aID, + const bool& aIsForApp, + const bool& aIsForBrowser) = 0; + virtual jsipc::JavaScriptChild* GetCPOWManager() = 0; +protected: + virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild(); + virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*); + + virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext, + const uint32_t& aChromeFlags, + const uint64_t& aID, + const bool& aIsForApp, + const bool& aIsForBrowser); + virtual bool DeallocPBrowserChild(PBrowserChild*); + + virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams); + virtual bool DeallocPBlobChild(PBlobChild*); + + virtual bool RecvAsyncMessage(const nsString& aMsg, + const ClonedMessageData& aData, + const InfallibleTArray& aCpows, + const IPC::Principal& aPrincipal); +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentChild, NS_ICONTENTCHILD_IID) + +} // dom +} // mozilla +#endif /* mozilla_dom_nsIContentChild_h */