Skip to content

Commit

Permalink
Bug 1832701 - Part 2: Add IPCTransferable for clipboard write paramet…
Browse files Browse the repository at this point in the history
…ers; r=nika

Move IPCTransferable* into a separated file to avoid circular dependency and
use `hg cp` in order to keep the history.

Differential Revision: https://phabricator.services.mozilla.com/D178070
  • Loading branch information
EdgarChen committed May 15, 2023
1 parent 287fc0f commit 6ef9eed
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 150 deletions.
46 changes: 46 additions & 0 deletions dom/base/nsContentUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7944,6 +7944,28 @@ nsresult nsContentUtils::IPCTransferableDataToTransferable(
return NS_OK;
}

nsresult nsContentUtils::IPCTransferableToTransferable(
const IPCTransferable& aIPCTransferable, bool aAddDataFlavor,
nsITransferable* aTransferable, const bool aFilterUnknownFlavors) {
nsresult rv =
IPCTransferableDataToTransferable(aIPCTransferable.data(), aAddDataFlavor,
aTransferable, aFilterUnknownFlavors);
NS_ENSURE_SUCCESS(rv, rv);

aTransferable->SetIsPrivateData(aIPCTransferable.isPrivateData());
aTransferable->SetRequestingPrincipal(aIPCTransferable.requestingPrincipal());
if (aIPCTransferable.cookieJarSettings().isSome()) {
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
net::CookieJarSettings::Deserialize(
aIPCTransferable.cookieJarSettings().ref(),
getter_AddRefs(cookieJarSettings));
aTransferable->SetCookieJarSettings(cookieJarSettings);
}
aTransferable->SetContentPolicyType(aIPCTransferable.contentPolicyType());
aTransferable->SetReferrerInfo(aIPCTransferable.referrerInfo());
return NS_OK;
}

nsresult nsContentUtils::IPCTransferableDataItemToVariant(
const IPCTransferableDataItem& aItem, nsIWritableVariant* aVariant) {
MOZ_ASSERT(aVariant);
Expand Down Expand Up @@ -8279,6 +8301,30 @@ void nsContentUtils::TransferableToIPCTransferableData(
}
}

void nsContentUtils::TransferableToIPCTransferable(
nsITransferable* aTransferable, IPCTransferable* aIPCTransferable,
bool aInSyncMessage, mozilla::dom::ContentParent* aParent) {
IPCTransferableData ipcTransferableData;
TransferableToIPCTransferableData(aTransferable, &ipcTransferableData,
aInSyncMessage, aParent);

Maybe<net::CookieJarSettingsArgs> cookieJarSettingsArgs;
if (nsCOMPtr<nsICookieJarSettings> cookieJarSettings =
aTransferable->GetCookieJarSettings()) {
net::CookieJarSettingsArgs args;
net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(args);
cookieJarSettingsArgs = Some(std::move(args));
}

aIPCTransferable->data() = std::move(ipcTransferableData);
aIPCTransferable->isPrivateData() = aTransferable->GetIsPrivateData();
aIPCTransferable->requestingPrincipal() =
aTransferable->GetRequestingPrincipal();
aIPCTransferable->cookieJarSettings() = std::move(cookieJarSettingsArgs);
aIPCTransferable->contentPolicyType() = aTransferable->GetContentPolicyType();
aIPCTransferable->referrerInfo() = aTransferable->GetReferrerInfo();
}

Maybe<BigBuffer> nsContentUtils::GetSurfaceData(DataSourceSurface& aSurface,
size_t* aLength,
int32_t* aStride) {
Expand Down
11 changes: 11 additions & 0 deletions dom/base/nsContentUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ class Element;
class Event;
class EventTarget;
class HTMLInputElement;
class IPCTransferable;
class IPCTransferableData;
class IPCTransferableDataImageContainer;
class IPCTransferableDataItem;
Expand Down Expand Up @@ -2872,6 +2873,11 @@ class nsContentUtils {
const nsContentPolicyType& aContentPolicyType, bool aAddDataFlavor,
nsITransferable* aTransferable, const bool aFilterUnknownFlavors);

static nsresult IPCTransferableToTransferable(
const mozilla::dom::IPCTransferable& aIPCTransferable,
bool aAddDataFlavor, nsITransferable* aTransferable,
const bool aFilterUnknownFlavors);

static nsresult IPCTransferableDataItemToVariant(
const mozilla::dom::IPCTransferableDataItem& aItem,
nsIWritableVariant* aVariant);
Expand All @@ -2886,6 +2892,11 @@ class nsContentUtils {
mozilla::dom::IPCTransferableData* aTransferableData, bool aInSyncMessage,
mozilla::dom::ContentParent* aParent);

static void TransferableToIPCTransferable(
nsITransferable* aTransferable,
mozilla::dom::IPCTransferable* aIPCTransferable, bool aInSyncMessage,
mozilla::dom::ContentParent* aParent);

/*
* Get the pixel data from the given source surface and return it as a
* BigBuffer. The length and stride will be assigned from the surface.
Expand Down
24 changes: 6 additions & 18 deletions dom/ipc/ContentParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3467,16 +3467,13 @@ void ContentParent::OnVarChanged(const GfxVarUpdate& aVar) {
}

mozilla::ipc::IPCResult ContentParent::RecvSetClipboard(
const IPCTransferableData& aTransferableData, const bool& aIsPrivateData,
nsIPrincipal* aRequestingPrincipal,
mozilla::Maybe<CookieJarSettingsArgs> aCookieJarSettingsArgs,
const nsContentPolicyType& aContentPolicyType,
nsIReferrerInfo* aReferrerInfo, const int32_t& aWhichClipboard) {
const IPCTransferable& aTransferable, const int32_t& aWhichClipboard) {
// aRequestingPrincipal is allowed to be nullptr here.

if (!ValidatePrincipal(aRequestingPrincipal,
if (!ValidatePrincipal(aTransferable.requestingPrincipal(),
{ValidatePrincipalOptions::AllowNullPtr})) {
LogAndAssertFailedPrincipalValidationInfo(aRequestingPrincipal, __func__);
LogAndAssertFailedPrincipalValidationInfo(
aTransferable.requestingPrincipal(), __func__);
}

nsresult rv;
Expand All @@ -3487,18 +3484,9 @@ mozilla::ipc::IPCResult ContentParent::RecvSetClipboard(
do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
NS_ENSURE_SUCCESS(rv, IPC_OK());
trans->Init(nullptr);
trans->SetReferrerInfo(aReferrerInfo);

if (aCookieJarSettingsArgs.isSome()) {
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
net::CookieJarSettings::Deserialize(aCookieJarSettingsArgs.ref(),
getter_AddRefs(cookieJarSettings));
trans->SetCookieJarSettings(cookieJarSettings);
}

rv = nsContentUtils::IPCTransferableDataToTransferable(
aTransferableData, aIsPrivateData, aRequestingPrincipal,
aContentPolicyType, true /* aAddDataFlavor */, trans,
rv = nsContentUtils::IPCTransferableToTransferable(
aTransferable, true /* aAddDataFlavor */, trans,
true /* aFilterUnknownFlavors */);
NS_ENSURE_SUCCESS(rv, IPC_OK());

Expand Down
8 changes: 2 additions & 6 deletions dom/ipc/ContentParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -994,12 +994,8 @@ class ContentParent final : public PContentParent,

mozilla::ipc::IPCResult RecvGetGfxVars(nsTArray<GfxVarUpdate>* aVars);

mozilla::ipc::IPCResult RecvSetClipboard(
const IPCTransferableData& aTransferableData, const bool& aIsPrivateData,
nsIPrincipal* aRequestingPrincipal,
mozilla::Maybe<CookieJarSettingsArgs> aCookieJarSettingsArgs,
const nsContentPolicyType& aContentPolicyType,
nsIReferrerInfo* aReferrerInfo, const int32_t& aWhichClipboard);
mozilla::ipc::IPCResult RecvSetClipboard(const IPCTransferable& aTransferable,
const int32_t& aWhichClipboard);

mozilla::ipc::IPCResult RecvGetClipboard(
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
Expand Down
56 changes: 0 additions & 56 deletions dom/ipc/DOMTypes.ipdlh
Original file line number Diff line number Diff line change
Expand Up @@ -100,62 +100,6 @@ struct MessageData {
MessageDataType data;
};

struct IPCTransferableDataString
{
BigBuffer data;
};

struct IPCTransferableDataCString
{
BigBuffer data;
};

struct IPCTransferableDataInputStream
{
// NOTE: Editor currently relies on these input streams being synchronous, so
// we can't safely serialize them using IPCStream (see bug 1778565). Instead,
// they're serialized as a `BigBuffer`, and converted to a nsStringInputStream
// on the receiving side. If we are able to use async streams reliably in the
// future, we could consider switching the code which adds `nsIInputStream`s
// to the transferable to use `BlobImpl` instead, for more consistency between
// image formats.
BigBuffer data;
};

struct IPCTransferableDataImageContainer
{
BigBuffer data;
uint32_t width;
uint32_t height;
uint32_t stride;
SurfaceFormat format;
};

struct IPCTransferableDataBlob
{
IPCBlob blob;
};

union IPCTransferableDataType
{
IPCTransferableDataString;
IPCTransferableDataCString;
IPCTransferableDataInputStream;
IPCTransferableDataImageContainer;
IPCTransferableDataBlob;
};

struct IPCTransferableDataItem
{
nsCString flavor;
IPCTransferableDataType data;
};

struct IPCTransferableData
{
IPCTransferableDataItem[] items;
};

struct ScreenDetails {
LayoutDeviceIntRect rect;
DesktopIntRect rectDisplayPix;
Expand Down
85 changes: 85 additions & 0 deletions dom/ipc/IPCTransferable.ipdlh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
/* 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 IPCBlob;
include NeckoChannelParams;

using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
[RefCounted] using class nsIPrincipal from "nsIPrincipal.h";
[RefCounted] using class nsIReferrerInfo from "nsIReferrerInfo.h";
[MoveOnly] using class mozilla::ipc::BigBuffer from "mozilla/ipc/BigBuffer.h";

namespace mozilla {
namespace dom {

struct IPCTransferableDataString
{
BigBuffer data;
};

struct IPCTransferableDataCString
{
BigBuffer data;
};

struct IPCTransferableDataInputStream
{
// NOTE: Editor currently relies on these input streams being synchronous, so
// we can't safely serialize them using IPCStream (see bug 1778565). Instead,
// they're serialized as a `BigBuffer`, and converted to a nsStringInputStream
// on the receiving side. If we are able to use async streams reliably in the
// future, we could consider switching the code which adds `nsIInputStream`s
// to the transferable to use `BlobImpl` instead, for more consistency between
// image formats.
BigBuffer data;
};

struct IPCTransferableDataImageContainer
{
BigBuffer data;
uint32_t width;
uint32_t height;
uint32_t stride;
SurfaceFormat format;
};

struct IPCTransferableDataBlob
{
IPCBlob blob;
};

union IPCTransferableDataType
{
IPCTransferableDataString;
IPCTransferableDataCString;
IPCTransferableDataInputStream;
IPCTransferableDataImageContainer;
IPCTransferableDataBlob;
};

struct IPCTransferableDataItem
{
nsCString flavor;
IPCTransferableDataType data;
};

struct IPCTransferableData
{
IPCTransferableDataItem[] items;
};

struct IPCTransferable
{
IPCTransferableData data;
bool isPrivateData;
nullable nsIPrincipal requestingPrincipal;
CookieJarSettingsArgs? cookieJarSettings;
nsContentPolicyType contentPolicyType;
nullable nsIReferrerInfo referrerInfo;
};

} // namespace dom
} // namespace mozilla
2 changes: 2 additions & 0 deletions dom/ipc/PBrowser.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ include NeckoChannelParams;
include WindowGlobalTypes;
include IPCBlob;
include IPCStream;
include IPCTransferable;
include URIParams;
include PPrintingTypes;
include PTabContext;
Expand Down Expand Up @@ -864,6 +865,7 @@ child:
* Call PasteTransferable via a controller on the content process
* to handle the command content event, "pasteTransferable".
*/
// XXX Do we really need data other than IPCTransferableData? See bug 1833172.
async PasteTransferable(IPCTransferableData aTransferableData,
bool aIsPrivateData,
nullable nsIPrincipal aRequestingPrincipal,
Expand Down
8 changes: 2 additions & 6 deletions dom/ipc/PContent.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ include DOMTypes;
include WindowGlobalTypes;
include IPCBlob;
include IPCStream;
include IPCTransferable;
include PPrintingTypes;
include PTabContext;
include ProtocolTypes;
Expand Down Expand Up @@ -1217,12 +1218,7 @@ parent:
bool fromChromeContext, ClonedMessageData stack);

// Places the items within dataTransfer on the clipboard.
async SetClipboard(IPCTransferableData aTransferableData,
bool aIsPrivateData,
nullable nsIPrincipal aRequestingPrincipal,
CookieJarSettingsArgs? cookieJarSettings,
nsContentPolicyType aContentPolicyType,
nullable nsIReferrerInfo aReferrerInfo,
async SetClipboard(IPCTransferable aTransferable,
int32_t aWhichClipboard);

// Given a list of supported types, returns the clipboard data for the
Expand Down
1 change: 1 addition & 0 deletions dom/ipc/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ PREPROCESSED_IPDL_SOURCES += [

IPDL_SOURCES += [
"DOMTypes.ipdlh",
"IPCTransferable.ipdlh",
"MemoryReportTypes.ipdlh",
"PColorPicker.ipdl",
"PContentPermission.ipdlh",
Expand Down
18 changes: 4 additions & 14 deletions widget/ClipboardWriteRequestChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,10 @@ ClipboardWriteRequestChild::SetData(nsITransferable* aTransferable,
#endif

mIsValid = false;
IPCTransferableData ipcTransferableData;
nsContentUtils::TransferableToIPCTransferableData(
aTransferable, &ipcTransferableData, false, nullptr);
Maybe<net::CookieJarSettingsArgs> cookieJarSettingsArgs;
if (nsCOMPtr<nsICookieJarSettings> cookieJarSettings =
aTransferable->GetCookieJarSettings()) {
net::CookieJarSettingsArgs args;
net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(args);
cookieJarSettingsArgs = Some(std::move(args));
}
SendSetData(std::move(ipcTransferableData), aTransferable->GetIsPrivateData(),
aTransferable->GetRequestingPrincipal(), cookieJarSettingsArgs,
aTransferable->GetContentPolicyType(),
aTransferable->GetReferrerInfo());
IPCTransferable ipcTransferable;
nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable,
false, nullptr);
SendSetData(std::move(ipcTransferable));
return NS_OK;
}

Expand Down
Loading

0 comments on commit 6ef9eed

Please sign in to comment.