Bug 1773088 - Part 1: Stop requiring an actor to serialize blobs over IPC, r=asuth

This does a somewhat-shallow removal of the argument from the implementation
and all call-sites. Removing it from StructuredCloneData's serialization is
handled in the next part, as it is more widely used and complex.

Differential Revision: https://phabricator.services.mozilla.com/D148531
This commit is contained in:
Nika Layzell 2022-06-08 15:24:27 +00:00
parent 18034fa952
commit ffd5c3388d
18 changed files with 58 additions and 176 deletions

View File

@ -8122,31 +8122,18 @@ void nsContentUtils::TransferableToIPCTransferable(
}
if (blobImpl) {
IPCDataTransferData data;
IPCBlob ipcBlob;
// If we failed to create the blob actor, then this blob probably
// can't get the file size for the underlying file, ignore it for
// now. TODO pass this through anyway.
if (aChild) {
nsresult rv = IPCBlobUtils::Serialize(blobImpl, aChild, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
data = ipcBlob;
} else if (aParent) {
nsresult rv = IPCBlobUtils::Serialize(blobImpl, aParent, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
data = ipcBlob;
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
item->flavor() = flavorStr;
item->data() = data;
item->data() = ipcBlob;
item->dataType() = TransferableDataType::Blob;
}
}

View File

@ -157,8 +157,7 @@ void BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
// Serialize Blob objects for this message.
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], parent->Manager(),
newBlobImpls[i]);
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], newBlobImpls[i]);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}

View File

@ -47,8 +47,7 @@ mozilla::ipc::IPCResult FileCreatorParent::CreateAndShareFile(
"FileCreatorParent::CreateAndShareFile return", [self, blobImpl]() {
if (self->mIPCActive) {
IPCBlob ipcBlob;
nsresult rv = dom::IPCBlobUtils::Serialize(
blobImpl, self->Manager(), ipcBlob);
nsresult rv = dom::IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(self, FileCreationErrorResult(rv));
return;

View File

@ -20,11 +20,7 @@
#include "StreamBlobImpl.h"
#include "prtime.h"
namespace mozilla {
using namespace ipc;
namespace dom::IPCBlobUtils {
namespace mozilla::dom::IPCBlobUtils {
already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob) {
nsCOMPtr<nsIInputStream> inputStream;
@ -72,9 +68,7 @@ already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob) {
return blobImpl.forget();
}
template <typename M>
nsresult SerializeInternal(BlobImpl* aBlobImpl, M* aManager,
IPCBlob& aIPCBlob) {
nsresult Serialize(BlobImpl* aBlobImpl, IPCBlob& aIPCBlob) {
MOZ_ASSERT(aBlobImpl);
nsAutoString value;
@ -136,7 +130,7 @@ nsresult SerializeInternal(BlobImpl* aBlobImpl, M* aManager,
return NS_OK;
}
IPCStream stream;
mozilla::ipc::IPCStream stream;
if (!mozilla::ipc::SerializeIPCStream(inputStream.forget(), stream,
/* aAllowLazy */ true)) {
return NS_ERROR_FAILURE;
@ -145,93 +139,41 @@ nsresult SerializeInternal(BlobImpl* aBlobImpl, M* aManager,
return NS_OK;
}
nsresult Serialize(BlobImpl* aBlobImpl, ContentChild* aManager,
IPCBlob& aIPCBlob) {
return SerializeInternal(aBlobImpl, aManager, aIPCBlob);
}
} // namespace mozilla::dom::IPCBlobUtils
nsresult Serialize(BlobImpl* aBlobImpl, PBackgroundChild* aManager,
IPCBlob& aIPCBlob) {
return SerializeInternal(aBlobImpl, aManager, aIPCBlob);
}
namespace IPC {
nsresult Serialize(BlobImpl* aBlobImpl, ContentParent* aManager,
IPCBlob& aIPCBlob) {
return SerializeInternal(aBlobImpl, aManager, aIPCBlob);
}
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->GetProtocolId()) {
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");
}
}
} // namespace dom::IPCBlobUtils
namespace ipc {
void IPDLParamTraits<mozilla::dom::BlobImpl*>::Write(
IPC::MessageWriter* aWriter, IProtocol* aActor,
mozilla::dom::BlobImpl* aParam) {
void ParamTraits<mozilla::dom::BlobImpl*>::Write(
IPC::MessageWriter* aWriter, mozilla::dom::BlobImpl* aParam) {
nsresult rv;
mozilla::dom::IPCBlob ipcblob;
if (aParam) {
rv = mozilla::dom::IPCBlobUtils::SerializeUntyped(aParam, aActor, ipcblob);
rv = mozilla::dom::IPCBlobUtils::Serialize(aParam, ipcblob);
}
if (!aParam || NS_WARN_IF(NS_FAILED(rv))) {
WriteIPDLParam(aWriter, aActor, false);
WriteParam(aWriter, false);
} else {
WriteIPDLParam(aWriter, aActor, true);
WriteIPDLParam(aWriter, aActor, ipcblob);
WriteParam(aWriter, true);
WriteParam(aWriter, ipcblob);
}
}
bool IPDLParamTraits<mozilla::dom::BlobImpl*>::Read(
IPC::MessageReader* aReader, IProtocol* aActor,
RefPtr<mozilla::dom::BlobImpl>* aResult) {
bool ParamTraits<mozilla::dom::BlobImpl*>::Read(
IPC::MessageReader* aReader, RefPtr<mozilla::dom::BlobImpl>* aResult) {
*aResult = nullptr;
bool notnull = false;
if (!ReadIPDLParam(aReader, aActor, &notnull)) {
if (!ReadParam(aReader, &notnull)) {
return false;
}
if (notnull) {
mozilla::dom::IPCBlob ipcblob;
if (!ReadIPDLParam(aReader, aActor, &ipcblob)) {
if (!ReadParam(aReader, &ipcblob)) {
return false;
}
*aResult = mozilla::dom::IPCBlobUtils::Deserialize(ipcblob);
}
return true;
}
} // namespace ipc
} // namespace mozilla
} // namespace IPC

View File

@ -236,60 +236,33 @@
* we can keep the actors on the main-thread because no Workers are involved.
*/
namespace mozilla {
namespace ipc {
class IProtocol;
class PBackgroundChild;
class PBackgroundParent;
} // namespace ipc
namespace dom {
namespace mozilla::dom {
class IPCBlob;
class ContentChild;
class ContentParent;
namespace IPCBlobUtils {
already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob);
// These 4 methods serialize aBlobImpl into aIPCBlob using the right manager.
nsresult Serialize(BlobImpl* aBlobImpl, ContentChild* aManager,
IPCBlob& aIPCBlob);
nsresult Serialize(BlobImpl* aBlobImpl,
mozilla::ipc::PBackgroundChild* aManager, IPCBlob& aIPCBlob);
nsresult Serialize(BlobImpl* aBlobImpl, ContentParent* 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);
nsresult Serialize(BlobImpl* aBlobImpl, IPCBlob& aIPCBlob);
} // namespace IPCBlobUtils
} // namespace dom
} // namespace mozilla::dom
namespace IPC {
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<mozilla::dom::BlobImpl*> {
static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
struct ParamTraits<mozilla::dom::BlobImpl*> {
static void Write(IPC::MessageWriter* aWriter,
mozilla::dom::BlobImpl* aParam);
static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
static bool Read(IPC::MessageReader* aReader,
RefPtr<mozilla::dom::BlobImpl>* aResult);
};
} // namespace ipc
} // namespace mozilla
} // namespace IPC
#endif // mozilla_dom_IPCBlobUtils_h

View File

@ -77,7 +77,7 @@ mozilla::ipc::IPCResult TemporaryIPCBlobParent::RecvOperationDone(
PR_Close(prfile);
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(blobImpl, Manager(), ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(this, NS_ERROR_FAILURE);
return IPC_OK();

View File

@ -148,14 +148,13 @@ void BroadcastBlobURLRegistration(const nsACString& aURI,
return;
}
dom::ContentChild* cc = dom::ContentChild::GetSingleton();
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, cc, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
dom::ContentChild* cc = dom::ContentChild::GetSingleton();
Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
nsCString(aURI), ipcBlob, IPC::Principal(aPrincipal), aAgentClusterId));
}

View File

@ -235,8 +235,7 @@ FileSystemResponseValue GetDirectoryListingTaskParent::GetSuccessRequestResult(
blobImpl->SetDOMPath(filePath);
IPCBlob ipcBlob;
rv =
IPCBlobUtils::Serialize(blobImpl, mRequestParent->Manager(), ipcBlob);
rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}

View File

@ -200,7 +200,7 @@ FileSystemResponseValue GetFileOrDirectoryTaskParent::GetSuccessRequestResult(
RefPtr<BlobImpl> blobImpl = new FileBlobImpl(mTargetPath);
IPCBlob ipcBlob;
aRv = IPCBlobUtils::Serialize(blobImpl, mRequestParent->Manager(), ipcBlob);
aRv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(aRv.Failed())) {
return FileSystemDirectoryResponse();
}

View File

@ -512,8 +512,7 @@ class GetFilesHelperParentCallback final : public GetFilesCallback {
ipcBlobs.SetLength(aBlobImpls.Length());
for (uint32_t i = 0; i < aBlobImpls.Length(); ++i) {
nsresult rv = IPCBlobUtils::Serialize(
aBlobImpls[i], mParent->mContentParent, ipcBlobs[i]);
nsresult rv = IPCBlobUtils::Serialize(aBlobImpls[i], ipcBlobs[i]);
if (NS_WARN_IF(NS_FAILED(rv))) {
mParent->mContentParent->SendGetFilesResponseAndForget(
mParent->mUUID, GetFilesResponseFailure(NS_ERROR_OUT_OF_MEMORY));

View File

@ -188,8 +188,7 @@ FileSystemResponseValue GetFilesTaskParent::GetSuccessRequestResult(
for (unsigned i = 0; i < mTargetBlobImplArray.Length(); i++) {
IPCBlob ipcBlob;
aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i],
mRequestParent->Manager(), ipcBlob);
aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i], ipcBlob);
if (NS_WARN_IF(aRv.Failed())) {
FileSystemFilesResponse response;
return response;

View File

@ -5592,12 +5592,10 @@ RefPtr<BlobImpl> CreateFileBlobImpl(const Database& aDatabase,
}
Result<nsTArray<SerializedStructuredCloneFile>, nsresult>
SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
const SafeRefPtr<Database>& aDatabase,
SerializeStructuredCloneFiles(const SafeRefPtr<Database>& aDatabase,
const nsTArray<StructuredCloneFileParent>& aFiles,
bool aForPreprocess) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aBackgroundActor);
MOZ_ASSERT(aDatabase);
if (aFiles.IsEmpty()) {
@ -5620,7 +5618,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
return !aForPreprocess ||
file.Type() == StructuredCloneFileBase::eStructuredClone;
},
[&directory, &aDatabase, aBackgroundActor, aForPreprocess](
[&directory, &aDatabase, aForPreprocess](
const auto& file) -> Result<SerializedStructuredCloneFile, nsresult> {
const int64_t fileId = file.FileInfo().Id();
MOZ_ASSERT(fileId > 0);
@ -5647,8 +5645,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
IPCBlob ipcBlob;
// This can only fail if the child has crashed.
QM_TRY(MOZ_TO_RESULT(IPCBlobUtils::Serialize(impl, aBackgroundActor,
ipcBlob)),
QM_TRY(MOZ_TO_RESULT(IPCBlobUtils::Serialize(impl, ipcBlob)),
Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR),
IDB_REPORT_INTERNAL_ERR_LAMBDA);
@ -11949,8 +11946,7 @@ void ValueCursorBase::ProcessFiles(CursorResponse& aResponse,
MOZ_ASSERT(this->mDatabase);
QM_TRY_UNWRAP(serializedInfo->files(),
SerializeStructuredCloneFiles((*this->mBackgroundParent),
this->mDatabase, files,
SerializeStructuredCloneFiles(this->mDatabase, files,
/* aForPreprocess */ false),
QM_VOID, [&aResponse](const nsresult result) {
aResponse = ClampResultCode(result);
@ -19860,7 +19856,7 @@ Result<T, nsresult> ObjectStoreGetRequestOp::ConvertResponse(
}
QM_TRY_UNWRAP(result.files(), SerializeStructuredCloneFiles(
mBackgroundParent, mDatabase, aInfo.Files(),
mDatabase, aInfo.Files(),
std::is_same_v<T, PreprocessInfo>));
return result;
@ -20407,9 +20403,8 @@ void IndexGetRequestOp::GetResponse(RequestResponse& aResponse,
result.data().data = info.ReleaseData();
QM_TRY_UNWRAP(result.files(),
SerializeStructuredCloneFiles(mBackgroundParent, mDatabase,
info.Files(), false));
QM_TRY_UNWRAP(result.files(), SerializeStructuredCloneFiles(
mDatabase, info.Files(), false));
return result;
};

View File

@ -790,12 +790,8 @@ PBackgroundIDBDatabaseFileChild* IDBDatabase::GetOrCreateFileActorForBlob(
BlobImpl* blobImpl = aBlob.Impl();
MOZ_ASSERT(blobImpl);
PBackgroundChild* backgroundManager =
mBackgroundActor->Manager()->Manager();
MOZ_ASSERT(backgroundManager);
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(blobImpl, backgroundManager, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}

View File

@ -610,12 +610,8 @@ RefPtr<IDBFileRequest> IDBFileHandle::WriteOrAppend(Blob& aValue, bool aAppend,
return nullptr;
}
PBackgroundChild* backgroundActor = BackgroundChild::GetForCurrentThread();
MOZ_ASSERT(backgroundActor);
IPCBlob ipcBlob;
nsresult rv =
IPCBlobUtils::Serialize(aValue.Impl(), backgroundActor, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(aValue.Impl(), ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
return nullptr;

View File

@ -3194,7 +3194,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
}
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, this, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
@ -5776,7 +5776,7 @@ void ContentParent::BroadcastBlobURLRegistration(
}
IPCBlob ipcBlob;
rv = IPCBlobUtils::Serialize(aBlobImpl, cp, ipcBlob);
rv = IPCBlobUtils::Serialize(aBlobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
break;
}
@ -6091,7 +6091,7 @@ void ContentParent::TransmitBlobURLsForPrincipal(nsIPrincipal* aPrincipal) {
}
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, this, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
@ -7250,7 +7250,7 @@ mozilla::ipc::IPCResult ContentParent::RecvBlobURLDataRequest(
}
IPCBlob ipcBlob;
nsresult rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResolver(rv);

View File

@ -156,7 +156,7 @@ void FilePickerParent::SendFilesOrDirectories(
IPCBlob ipcBlob;
MOZ_ASSERT(aData[i].mType == BlobImplOrString::eBlobImpl);
nsresult rv = IPCBlobUtils::Serialize(aData[i].mBlobImpl, parent, ipcBlob);
nsresult rv = IPCBlobUtils::Serialize(aData[i].mBlobImpl, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
break;
}

View File

@ -344,8 +344,7 @@ void WritableSharedMap::SendTo(ContentParent* aParent) const {
nsTArray<IPCBlob> blobs(mBlobImpls.Length());
for (auto& blobImpl : mBlobImpls) {
nsresult rv =
IPCBlobUtils::Serialize(blobImpl, aParent, *blobs.AppendElement());
nsresult rv = IPCBlobUtils::Serialize(blobImpl, *blobs.AppendElement());
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}

View File

@ -169,8 +169,8 @@ bool BuildClonedMessageData(M* aManager, StructuredCloneData& aData,
}
for (uint32_t i = 0; i < blobImpls.Length(); ++i) {
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], aManager,
aClonedData.blobs()[i]);
nsresult rv =
IPCBlobUtils::Serialize(blobImpls[i], aClonedData.blobs()[i]);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}