diff --git a/ipc/glue/IPCStreamUtils.cpp b/ipc/glue/IPCStreamUtils.cpp index 7518e3812edd..6e098709fbf5 100644 --- a/ipc/glue/IPCStreamUtils.cpp +++ b/ipc/glue/IPCStreamUtils.cpp @@ -9,8 +9,8 @@ #include "nsIIPCSerializableInputStream.h" #include "mozilla/Assertions.h" -#include "mozilla/dom/nsIContentChild.h" -#include "mozilla/dom/PContentParent.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/File.h" #include "mozilla/ipc/FileDescriptorSetChild.h" #include "mozilla/ipc/FileDescriptorSetParent.h" @@ -625,5 +625,69 @@ AutoIPCStream::TakeOptionalValue() return *mOptionalValue; } +void +IPDLParamTraits>::Write(IPC::Message* aMsg, + IProtocol* aActor, + const nsCOMPtr& aParam) +{ + mozilla::ipc::AutoIPCStream autoStream; + bool ok = false; + bool found = false; + + // We can only serialize our nsIInputStream if it's going to be sent over one + // of the protocols we support, or a protocol which is managed by one of the + // protocols we support. + IProtocol* actor = aActor; + while (!found && actor) { + switch (actor->GetProtocolTypeId()) { + case PContentMsgStart: + if (actor->GetSide() == mozilla::ipc::ParentSide) { + ok = autoStream.Serialize( + aParam, static_cast(actor)); + } else { + MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide); + ok = autoStream.Serialize( + aParam, static_cast(actor)); + } + found = true; + break; + case PBackgroundMsgStart: + if (actor->GetSide() == mozilla::ipc::ParentSide) { + ok = autoStream.Serialize( + aParam, static_cast(actor)); + } else { + MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide); + ok = autoStream.Serialize( + aParam, static_cast(actor)); + } + found = true; + break; + } + + // Try the actor's manager. + actor = actor->Manager(); + } + + if (!found) { + aActor->FatalError("Attempt to send nsIInputStream over an unsupported ipdl protocol"); + } + MOZ_RELEASE_ASSERT(ok, "Failed to serialize nsIInputStream"); + + WriteIPDLParam(aMsg, aActor, autoStream.TakeOptionalValue()); +} + +bool +IPDLParamTraits>::Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, nsCOMPtr* aResult) +{ + mozilla::ipc::OptionalIPCStream ipcStream; + if (!ReadIPDLParam(aMsg, aIter, aActor, &ipcStream)) { + return false; + } + + *aResult = mozilla::ipc::DeserializeIPCStream(ipcStream); + return true; +} + } // namespace ipc } // namespace mozilla diff --git a/ipc/glue/IPCStreamUtils.h b/ipc/glue/IPCStreamUtils.h index 936b8b23ce03..9ccddc91ab88 100644 --- a/ipc/glue/IPCStreamUtils.h +++ b/ipc/glue/IPCStreamUtils.h @@ -8,6 +8,7 @@ #define mozilla_ipc_IPCStreamUtils_h #include "mozilla/ipc/IPCStream.h" +#include "nsCOMPtr.h" #include "nsIInputStream.h" namespace mozilla { @@ -187,6 +188,17 @@ private: AutoIPCStream& operator=(const AutoIPCStream&& aOther) = delete; }; +template<> +struct IPDLParamTraits> +{ + typedef nsCOMPtr paramType; + + static void Write(IPC::Message* aMsg, IProtocol* aActor, + const paramType& aParam); + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, paramType* aResult); +}; + } // namespace ipc } // namespace mozilla