author | Nika Layzell <nika@thelayzells.com> |
Fri, 02 Mar 2018 13:13:48 -0500 | |
changeset 412749 | 1c1e0d112e260b3213d81c429f25f99b34716eef |
parent 412748 | a6edd350b230916c11bcfbb5d68676b461bba28a |
child 412750 | 7dadb3852649b5184bf5960b7565b0f15bee9b09 |
push id | 33818 |
push user | apavel@mozilla.com |
push date | Wed, 11 Apr 2018 14:36:40 +0000 |
treeherder | mozilla-central@cfe6399e142c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | baku |
bugs | 1438026 |
milestone | 61.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
|
dom/file/ipc/IPCBlobUtils.cpp | file | annotate | diff | comparison | revisions | |
dom/file/ipc/IPCBlobUtils.h | file | annotate | diff | comparison | revisions |
--- a/dom/file/ipc/IPCBlobUtils.cpp +++ b/dom/file/ipc/IPCBlobUtils.cpp @@ -5,19 +5,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "IPCBlobUtils.h" #include "IPCBlobInputStream.h" #include "IPCBlobInputStreamChild.h" #include "IPCBlobInputStreamParent.h" #include "IPCBlobInputStreamStorage.h" #include "mozilla/dom/IPCBlob.h" -#include "mozilla/dom/nsIContentParent.h" #include "mozilla/ipc/BackgroundParent.h" +#include "mozilla/ipc/PBackgroundParent.h" +#include "mozilla/ipc/PBackgroundChild.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/ContentChild.h" #include "mozilla/ipc/IPCStreamUtils.h" +#include "mozilla/ipc/ProtocolUtils.h" #include "StreamBlobImpl.h" #include "prtime.h" namespace mozilla { using namespace ipc; namespace dom { @@ -254,11 +258,88 @@ Serialize(BlobImpl* aBlobImpl, nsIConten } nsresult Serialize(BlobImpl* aBlobImpl, PBackgroundParent* aManager, IPCBlob& aIPCBlob) { return SerializeInternal(aBlobImpl, aManager, aIPCBlob); } +nsresult +SerializeUntyped(BlobImpl* aBlobImpl, IProtocol* aActor, IPCBlob& aIPCBlob) +{ + // We always want to act on the toplevel protocol. + IProtocol* manager = aActor; + while (manager->Manager()) { + manager = manager->Manager(); + } + + // We always need the toplevel protocol + switch(manager->GetProtocolTypeId()) { + case PBackgroundMsgStart: + if (manager->GetSide() == mozilla::ipc::ParentSide) { + return SerializeInternal(aBlobImpl, + static_cast<PBackgroundParent*>(manager), + aIPCBlob); + } else { + return SerializeInternal(aBlobImpl, + static_cast<PBackgroundChild*>(manager), + aIPCBlob); + } + case PContentMsgStart: + if (manager->GetSide() == mozilla::ipc::ParentSide) { + return SerializeInternal(aBlobImpl, + static_cast<ContentParent*>(manager), + aIPCBlob); + } else { + return SerializeInternal(aBlobImpl, + static_cast<ContentChild*>(manager), + aIPCBlob); + } + default: + MOZ_CRASH("Unsupported protocol passed to BlobImpl serialize"); + } +} + } // IPCBlobUtils namespace } // dom namespace + +namespace ipc { +void +IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>>::Write( + IPC::Message* aMsg, IProtocol* aActor, + const RefPtr<mozilla::dom::BlobImpl>& aParam) +{ + nsresult rv; + mozilla::dom::IPCBlob ipcblob; + if (aParam) { + rv = mozilla::dom::IPCBlobUtils::SerializeUntyped(aParam, aActor, ipcblob); + } + if (!aParam || NS_WARN_IF(NS_FAILED(rv))) { + WriteIPDLParam(aMsg, aActor, false); + } else { + WriteIPDLParam(aMsg, aActor, true); + WriteIPDLParam(aMsg, aActor, ipcblob); + } +} + +bool +IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>>::Read( + const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, RefPtr<mozilla::dom::BlobImpl>* aResult) +{ + *aResult = nullptr; + + bool notnull = false; + if (!ReadIPDLParam(aMsg, aIter, aActor, ¬null)) { + return false; + } + if (notnull) { + mozilla::dom::IPCBlob ipcblob; + if (!ReadIPDLParam(aMsg, aIter, aActor, &ipcblob)) { + return false; + } + *aResult = mozilla::dom::IPCBlobUtils::Deserialize(ipcblob); + } + return true; +} +} // ipc namespace } // mozilla namespace
--- a/dom/file/ipc/IPCBlobUtils.h +++ b/dom/file/ipc/IPCBlobUtils.h @@ -2,17 +2,19 @@ /* vim: set ts=8 sts=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_IPCBlobUtils_h #define mozilla_dom_IPCBlobUtils_h +#include "mozilla/RefPtr.h" #include "mozilla/dom/File.h" +#include "mozilla/ipc/IPDLParamTraits.h" /* * Blobs and IPC * ~~~~~~~~~~~~~ * * Simplifying, DOM Blob objects are chunks of data with a content type and a * size. DOM Files are Blobs with a name. They are are used in many APIs and * they can be cloned and sent cross threads and cross processes. @@ -207,28 +209,33 @@ * When IPCBlobInputStream is serialized and sent to the parent process, start * and range are sent too and SlicedInputStream is used in the parent side as * well. */ namespace mozilla { namespace ipc { +class IProtocol; class PBackgroundChild; class PBackgroundParent; } namespace dom { class IPCBlob; class nsIContentChild; class nsIContentParent; namespace IPCBlobUtils { +// Typedef for use within ipdl files, as the full type cannot be written +// currently. +typedef RefPtr<BlobImpl> BlobImplPtr; + already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob); // These 4 methods serialize aBlobImpl into aIPCBlob using the right manager. nsresult Serialize(BlobImpl* aBlobImpl, nsIContentChild* aManager, IPCBlob& aIPCBlob); @@ -238,13 +245,33 @@ Serialize(BlobImpl* aBlobImpl, mozilla:: nsresult Serialize(BlobImpl* aBlobImpl, nsIContentParent* aManager, IPCBlob& aIPCBlob); nsresult Serialize(BlobImpl* aBlobImpl, mozilla::ipc::PBackgroundParent* aManager, IPCBlob& aIPCBlob); +// WARNING: If you pass any actor which does not have P{Content,Background} as +// its toplevel protocol, this method will MOZ_CRASH. +nsresult +SerializeUntyped(BlobImpl* aBlobImpl, mozilla::ipc::IProtocol* aActor, IPCBlob& aIPCBlob); + } // IPCBlobUtils } // dom namespace + +namespace ipc { +// ParamTraits implementation for BlobImpl. N.B: If the original BlobImpl cannot +// be successfully serialized, a warning will be produced and a nullptr will be +// sent over the wire. When Read()-ing a BlobImpl, +// __always make sure to handle null!__ +template<> +struct IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>> +{ + static void Write(IPC::Message* aMsg, IProtocol* aActor, + const RefPtr<mozilla::dom::BlobImpl>& aParam); + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, RefPtr<mozilla::dom::BlobImpl>* aResult); +}; +} // ipc namespace } // mozilla namespace #endif // mozilla_dom_IPCBlobUtils_h