зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1901197: do synchronous Content Analysis for clipboard operations on a background thread r=dlp-reviewers,ipc-reviewers,handyman
Differential Revision: https://phabricator.services.mozilla.com/D215457
This commit is contained in:
Родитель
7d29658155
Коммит
6ba11a66b8
|
@ -20,6 +20,9 @@
|
|||
# Used by `nsUpdateProcessor` to check for updates. May also be used for polling
|
||||
# the update process.
|
||||
UpdateProcessor
|
||||
# Used by `BackgroundClipboardContentAnalysisParent` to handle clipboard requests
|
||||
# from content processes.
|
||||
BkgrndClipboard
|
||||
|
||||
######
|
||||
# Thunderbird-only thread names
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "imgLoader.h"
|
||||
#include "ScrollingMetrics.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ClipboardContentAnalysisChild.h"
|
||||
#include "mozilla/ClipboardReadRequestChild.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/HangDetails.h"
|
||||
|
@ -1544,6 +1545,14 @@ mozilla::ipc::IPCResult ContentChild::RecvInitGMPService(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvInitClipboardContentAnalysis(
|
||||
Endpoint<PClipboardContentAnalysisChild>&& aEndpoint) {
|
||||
if (!ClipboardContentAnalysisChild::Create(std::move(aEndpoint))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvInitProfiler(
|
||||
Endpoint<PProfilerChild>&& aEndpoint) {
|
||||
mProfilerController = ChildProfilerController::Create(std::move(aEndpoint));
|
||||
|
|
|
@ -160,6 +160,9 @@ class ContentChild final : public PContentChild,
|
|||
mozilla::ipc::IPCResult RecvInitProfiler(
|
||||
Endpoint<PProfilerChild>&& aEndpoint);
|
||||
|
||||
mozilla::ipc::IPCResult RecvInitClipboardContentAnalysis(
|
||||
Endpoint<PClipboardContentAnalysisChild>&& aEndpoint);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGMPsChanged(
|
||||
nsTArray<GMPCapabilityData>&& capabilities);
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "mozilla/AntiTrackingUtils.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/ClipboardContentAnalysisParent.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/BenchmarkStorageParent.h"
|
||||
#include "mozilla/Casting.h"
|
||||
|
@ -1114,6 +1115,65 @@ static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement) {
|
|||
return docShell;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvCreateClipboardContentAnalysis() {
|
||||
Endpoint<PClipboardContentAnalysisParent> parentEndpoint;
|
||||
Endpoint<PClipboardContentAnalysisChild> childEndpoint;
|
||||
|
||||
if (mClipboardContentAnalysisCreated) {
|
||||
return IPC_FAIL(this, "ClipboardContentAnalysisParent already created");
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
rv = PClipboardContentAnalysis::CreateEndpoints(
|
||||
base::GetCurrentProcId(), OtherPid(), &parentEndpoint, &childEndpoint);
|
||||
if (NS_FAILED(rv)) {
|
||||
return IPC_FAIL(this, "CreateEndpoints failed");
|
||||
}
|
||||
|
||||
if (!mClipboardContentAnalysisThread) {
|
||||
rv = NS_NewNamedThread("BkgrndClipboard",
|
||||
getter_AddRefs(mClipboardContentAnalysisThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL(this, "NS_NewNamedThread failed");
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ContentParent> contentParent = this;
|
||||
// Bind the new endpoint to the backgroundClipboardContentAnalysis thread,
|
||||
// then send them from the main thread.
|
||||
rv = NS_DispatchToThreadQueue(
|
||||
NS_NewRunnableFunction(
|
||||
"Create ClipboardContentAnalysisParent",
|
||||
[contentParent = std::move(contentParent),
|
||||
parentEndpoint = std::move(parentEndpoint),
|
||||
childEndpoint = std::move(childEndpoint)]() mutable {
|
||||
RefPtr<ClipboardContentAnalysisParent> parentActor =
|
||||
new ClipboardContentAnalysisParent();
|
||||
parentEndpoint.Bind(parentActor, nullptr);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction(
|
||||
"SendInitClipboardContentAnalysis",
|
||||
[contentParent = std::move(contentParent),
|
||||
childEndpoint = std::move(childEndpoint)]() mutable {
|
||||
DebugOnly<bool> success =
|
||||
contentParent->SendInitClipboardContentAnalysis(
|
||||
std::move(childEndpoint));
|
||||
MOZ_ASSERT(success,
|
||||
"SendInitClipboardContentAnalysis failed");
|
||||
}),
|
||||
0);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Failed to dispatch "
|
||||
"SendInitClipboardContentAnalysis");
|
||||
}),
|
||||
mClipboardContentAnalysisThread, EventQueuePriority::Normal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return IPC_FAIL(this, "NS_DispatchToThreadQueue failed");
|
||||
}
|
||||
mClipboardContentAnalysisCreated = true;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvCreateGMPService() {
|
||||
Endpoint<PGMPServiceParent> parent;
|
||||
Endpoint<PGMPServiceChild> child;
|
||||
|
@ -2531,6 +2591,7 @@ ContentParent::ContentParent(const nsACString& aRemoteType)
|
|||
mIsInputPriorityEventEnabled(false),
|
||||
mIsInPool(false),
|
||||
mGMPCreated(false),
|
||||
mClipboardContentAnalysisCreated(false),
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
mBlockShutdownCalled(false),
|
||||
#endif
|
||||
|
@ -3115,10 +3176,8 @@ mozilla::ipc::IPCResult ContentParent::RecvSetClipboard(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static Result<nsCOMPtr<nsITransferable>, nsresult> CreateTransferable(
|
||||
const nsTArray<nsCString>& aTypes) {
|
||||
/* static */ Result<nsCOMPtr<nsITransferable>, nsresult>
|
||||
ContentParent::CreateClipboardTransferable(const nsTArray<nsCString>& aTypes) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsITransferable> trans =
|
||||
do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
|
||||
|
@ -3141,8 +3200,6 @@ static Result<nsCOMPtr<nsITransferable>, nsresult> CreateTransferable(
|
|||
return std::move(trans);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvGetClipboard(
|
||||
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
|
||||
const MaybeDiscarded<WindowContext>& aRequestingWindowContext,
|
||||
|
@ -3171,7 +3228,7 @@ mozilla::ipc::IPCResult ContentParent::RecvGetClipboard(
|
|||
}
|
||||
|
||||
// Create transferable
|
||||
auto result = CreateTransferable(aTypes);
|
||||
auto result = CreateClipboardTransferable(aTypes);
|
||||
if (result.isErr()) {
|
||||
*aTransferableDataOrError = result.unwrapErr();
|
||||
return IPC_OK();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "mozilla/MemoryReportingProcess.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RecursiveMutex.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIRemoteTab.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIDOMGeoPositionCallback.h"
|
||||
#include "nsIDOMGeoPositionErrorCallback.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
@ -228,6 +230,12 @@ class ContentParent final : public PContentParent,
|
|||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
|
||||
bool aPreferUsed = false, uint64_t aBrowserId = 0);
|
||||
|
||||
/**
|
||||
* Create an nsITransferable with the specified data flavor types.
|
||||
*/
|
||||
static mozilla::Result<nsCOMPtr<nsITransferable>, nsresult>
|
||||
CreateClipboardTransferable(const nsTArray<nsCString>& aTypes);
|
||||
|
||||
/**
|
||||
* Asynchronously wait for this content process to finish launching, such that
|
||||
* the ContentParent actor is ready for IPC.
|
||||
|
@ -343,6 +351,7 @@ class ContentParent final : public PContentParent,
|
|||
// been updated and so full reflows are in order.
|
||||
static void NotifyUpdatedFonts(bool aFullRebuild);
|
||||
|
||||
mozilla::ipc::IPCResult RecvCreateClipboardContentAnalysis();
|
||||
mozilla::ipc::IPCResult RecvCreateGMPService();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
|
||||
|
@ -1510,6 +1519,9 @@ class ContentParent final : public PContentParent,
|
|||
|
||||
// True if we already created a GMP service.
|
||||
uint8_t mGMPCreated : 1;
|
||||
// True if we already created the
|
||||
// ClipboardContentAnalysis actor
|
||||
uint8_t mClipboardContentAnalysisCreated : 1;
|
||||
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
bool mBlockShutdownCalled;
|
||||
|
@ -1590,6 +1602,8 @@ class ContentParent final : public PContentParent,
|
|||
|
||||
bool mIsSignaledImpendingShutdown = false;
|
||||
bool mIsNotifiedShutdownSuccess = false;
|
||||
|
||||
nsCOMPtr<nsIThread> mClipboardContentAnalysisThread;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(ContentParent, NS_CONTENTPARENT_IID)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
include protocol PBackgroundStarter;
|
||||
include protocol PBrowser;
|
||||
include protocol PClipboardContentAnalysis;
|
||||
include protocol PClipboardReadRequest;
|
||||
include protocol PClipboardWriteRequest;
|
||||
include protocol PCompositorManager;
|
||||
|
@ -578,6 +579,7 @@ child:
|
|||
async InitGMPService(Endpoint<PGMPServiceChild> service);
|
||||
async InitProcessHangMonitor(Endpoint<PProcessHangMonitorChild> hangMonitor);
|
||||
async InitProfiler(Endpoint<PProfilerChild> aEndpoint);
|
||||
async InitClipboardContentAnalysis(Endpoint<PClipboardContentAnalysisChild> aEndpoint);
|
||||
|
||||
// Give the content process its endpoints to the compositor.
|
||||
async InitRendering(
|
||||
|
@ -1088,6 +1090,8 @@ parent:
|
|||
|
||||
async CreateGMPService();
|
||||
|
||||
async CreateClipboardContentAnalysis();
|
||||
|
||||
async InitStreamFilter(uint64_t channelId, nsString addonId)
|
||||
returns (Endpoint<PStreamFilterChild> aEndpoint);
|
||||
|
||||
|
|
|
@ -96,6 +96,8 @@ description = Only used by gtests
|
|||
description = Only used by gtests
|
||||
|
||||
# Clipboard
|
||||
[PClipboardContentAnalysis::GetClipboard]
|
||||
description = Legacy synchronous clipboard API
|
||||
[PContent::GetClipboard]
|
||||
description = Legacy synchronous clipboard API
|
||||
[PContent::ClipboardHasType]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "ClipboardContentAnalysisChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
StaticRefPtr<ClipboardContentAnalysisChild>
|
||||
ClipboardContentAnalysisChild::sSingleton;
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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_WIDGET_CLIPBOARDCONTENTANALYSISCHILD_H_
|
||||
#define MOZILLA_WIDGET_CLIPBOARDCONTENTANALYSISCHILD_H_
|
||||
|
||||
#include "mozilla/ipc/Endpoint.h"
|
||||
#include "mozilla/PClipboardContentAnalysisChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
class ClipboardContentAnalysisChild final
|
||||
: public PClipboardContentAnalysisChild {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ClipboardContentAnalysisChild, override)
|
||||
|
||||
static bool Create(Endpoint<PClipboardContentAnalysisChild>&& aEndpoint) {
|
||||
MOZ_ASSERT(!sSingleton);
|
||||
sSingleton = new ClipboardContentAnalysisChild();
|
||||
DebugOnly<bool> success = aEndpoint.Bind(sSingleton);
|
||||
MOZ_ASSERT(success);
|
||||
return true;
|
||||
}
|
||||
static ClipboardContentAnalysisChild* GetSingleton() { return sSingleton; }
|
||||
void ActorDestroy(ActorDestroyReason aReason) override final {
|
||||
// There's only one singleton, so remove our reference to it.
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
friend PClipboardContentAnalysisChild;
|
||||
ClipboardContentAnalysisChild() { MOZ_ASSERT(XRE_IsContentProcess()); }
|
||||
~ClipboardContentAnalysisChild() = default;
|
||||
static StaticRefPtr<ClipboardContentAnalysisChild> sSingleton;
|
||||
};
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_WIDGET_CLIPBOARDCONTENTANALYSISCHILD_H_
|
|
@ -0,0 +1,165 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "ContentAnalysis.h"
|
||||
#include "mozilla/ClipboardContentAnalysisParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "nsBaseClipboard.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsID.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
||||
namespace mozilla {
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
|
||||
ipc::IPCResult ClipboardContentAnalysisParent::RecvGetClipboard(
|
||||
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
|
||||
const uint64_t& aRequestingWindowContextId,
|
||||
IPCTransferableDataOrError* aTransferableDataOrError) {
|
||||
// The whole point of having this actor is that it runs on a background thread
|
||||
// and so waiting for the content analysis result won't cause the main thread
|
||||
// to use SpinEventLoopUntil() which can cause a shutdownhang per bug 1901197.
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
RefPtr<nsIThread> actorThread = NS_GetCurrentThread();
|
||||
NS_ASSERTION(actorThread, "NS_GetCurrentThread() should not fail");
|
||||
// Ideally this would be a Maybe<Result>, but Result<> doesn't have a way to
|
||||
// get a reference to the IPCTransferableData inside it which makes it awkward
|
||||
// to use in this case.
|
||||
mozilla::Maybe<mozilla::Variant<IPCTransferableData, nsresult>>
|
||||
maybeTransferableResult;
|
||||
std::atomic<bool> transferableResultSet = false;
|
||||
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
__func__, [actorThread, aTypes = std::move(aTypes), aWhichClipboard,
|
||||
aRequestingWindowContextId, &maybeTransferableResult,
|
||||
&transferableResultSet]() {
|
||||
nsresult rv = NS_OK;
|
||||
// Make sure we reply to the actor thread on error.
|
||||
auto sendRv = MakeScopeExit([&]() {
|
||||
maybeTransferableResult = Some(AsVariant(rv));
|
||||
transferableResultSet = true;
|
||||
// Wake up the actor thread so SpinEventLoopUntil() can check its
|
||||
// condition again.
|
||||
NS_DispatchToThreadQueue(NS_NewRunnableFunction(__func__, []() {}),
|
||||
actorThread, EventQueuePriority::Normal);
|
||||
});
|
||||
nsCOMPtr<nsIClipboard> clipboard;
|
||||
RefPtr<dom::WindowGlobalParent> window =
|
||||
dom::WindowGlobalParent::GetByInnerWindowId(
|
||||
aRequestingWindowContextId);
|
||||
// We expect content processes to always pass a non-null window so
|
||||
// Content Analysis can analyze it. (if Content Analysis is
|
||||
// active) There may be some cases when a window is closing, etc.,
|
||||
// in which case returning no clipboard content should not be a
|
||||
// problem.
|
||||
if (!window) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->IsDiscarded()) {
|
||||
NS_WARNING(
|
||||
"discarded window passed to RecvGetClipboard(); returning "
|
||||
"no clipboard "
|
||||
"content");
|
||||
rv = NS_ERROR_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve clipboard
|
||||
clipboard = do_GetService(kCClipboardCID, &rv);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
auto transferableToCheck =
|
||||
dom::ContentParent::CreateClipboardTransferable(aTypes);
|
||||
if (transferableToCheck.isErr()) {
|
||||
rv = transferableToCheck.unwrapErr();
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass nullptr for the window here because we will be doing
|
||||
// content analysis ourselves asynchronously (so it doesn't block
|
||||
// main thread we're running on now)
|
||||
nsCOMPtr transferable = transferableToCheck.unwrap();
|
||||
rv = clipboard->GetData(transferable, aWhichClipboard, nullptr);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
auto contentAnalysisCallback =
|
||||
mozilla::MakeRefPtr<mozilla::contentanalysis::ContentAnalysis::
|
||||
SafeContentAnalysisResultCallback>(
|
||||
[actorThread, transferable, aRequestingWindowContextId,
|
||||
&maybeTransferableResult, &transferableResultSet](
|
||||
RefPtr<nsIContentAnalysisResult>&& aResult) {
|
||||
bool shouldAllow = aResult->GetShouldAllowContent();
|
||||
if (!shouldAllow) {
|
||||
maybeTransferableResult =
|
||||
Some(AsVariant(NS_ERROR_CONTENT_BLOCKED));
|
||||
} else {
|
||||
IPCTransferableData transferableData;
|
||||
RefPtr<dom::WindowGlobalParent> window =
|
||||
dom::WindowGlobalParent::GetByInnerWindowId(
|
||||
aRequestingWindowContextId);
|
||||
if (!window && window->IsDiscarded()) {
|
||||
maybeTransferableResult =
|
||||
Some(AsVariant(NS_ERROR_UNEXPECTED));
|
||||
} else {
|
||||
maybeTransferableResult =
|
||||
Some(AsVariant(IPCTransferableData()));
|
||||
nsContentUtils::TransferableToIPCTransferableData(
|
||||
transferable,
|
||||
&(maybeTransferableResult.ref()
|
||||
.as<IPCTransferableData>()),
|
||||
true /* aInSyncMessage */,
|
||||
window->BrowsingContext()->GetContentParent());
|
||||
}
|
||||
}
|
||||
transferableResultSet = true;
|
||||
|
||||
// Setting maybeTransferableResult is done on the main thread
|
||||
// instead of inside the runnable function here because some
|
||||
// of the objects that can be inside a maybeTransferableResult
|
||||
// are not thread-safe.
|
||||
// Wake up the actor thread so SpinEventLoopUntil() can check
|
||||
// its condition again.
|
||||
NS_DispatchToThreadQueue(
|
||||
NS_NewRunnableFunction(__func__, []() {}), actorThread,
|
||||
EventQueuePriority::Normal);
|
||||
});
|
||||
|
||||
contentanalysis::ContentAnalysis::CheckClipboardContentAnalysis(
|
||||
static_cast<nsBaseClipboard*>(clipboard.get()), window,
|
||||
transferable, aWhichClipboard, contentAnalysisCallback);
|
||||
|
||||
sendRv.release();
|
||||
}));
|
||||
|
||||
mozilla::SpinEventLoopUntil(
|
||||
"Waiting for clipboard and content analysis"_ns,
|
||||
[&transferableResultSet] { return transferableResultSet.load(); });
|
||||
|
||||
NS_ASSERTION(maybeTransferableResult.isSome(),
|
||||
"maybeTransferableResult should be set when "
|
||||
"transferableResultSet is true!");
|
||||
auto& transferableResult = *maybeTransferableResult;
|
||||
if (transferableResult.is<nsresult>()) {
|
||||
*aTransferableDataOrError = transferableResult.as<nsresult>();
|
||||
NS_WARNING(
|
||||
nsPrintfCString("ClipboardContentAnalysisParent::"
|
||||
"RecvGetClipboard got error %x",
|
||||
static_cast<int>(transferableResult.as<nsresult>()))
|
||||
.get());
|
||||
} else {
|
||||
*aTransferableDataOrError =
|
||||
std::move(transferableResult.as<IPCTransferableData>());
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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_WIDGET_CLIPBOARDCONTENTANALYSISPARENT_H_
|
||||
#define MOZILLA_WIDGET_CLIPBOARDCONTENTANALYSISPARENT_H_
|
||||
|
||||
#include "mozilla/PClipboardContentAnalysisParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ClipboardContentAnalysisParent final
|
||||
: public PClipboardContentAnalysisParent {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ClipboardContentAnalysisParent, override)
|
||||
|
||||
private:
|
||||
~ClipboardContentAnalysisParent() = default;
|
||||
|
||||
public:
|
||||
ipc::IPCResult RecvGetClipboard(
|
||||
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
|
||||
const uint64_t& aRequestingWindowContextId,
|
||||
IPCTransferableDataOrError* aTransferableDataOrError);
|
||||
};
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_WIDGET_CLIPBOARDCONTENTANALYSISPARENT_H_
|
|
@ -0,0 +1,24 @@
|
|||
/* -*- tab-width: 2; 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 IPCTransferable;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
[ChildProc=Content]
|
||||
sync protocol PClipboardContentAnalysis
|
||||
{
|
||||
parent:
|
||||
// Given a list of supported types, returns the clipboard data for the
|
||||
// first type that matches.
|
||||
// aRequestingWindowContext is the window that is requesting the clipboard,
|
||||
// which is used for content analysis.
|
||||
sync GetClipboard(nsCString[] aTypes, int32_t aWhichClipboard,
|
||||
uint64_t aRequestingWindowContextId)
|
||||
returns (IPCTransferableDataOrError transferableDataOrError);
|
||||
};
|
||||
|
||||
}
|
|
@ -166,6 +166,8 @@ EXPORTS += [
|
|||
|
||||
EXPORTS.mozilla += [
|
||||
"BasicEvents.h",
|
||||
"ClipboardContentAnalysisChild.h",
|
||||
"ClipboardContentAnalysisParent.h",
|
||||
"ClipboardReadRequestChild.h",
|
||||
"ClipboardReadRequestParent.h",
|
||||
"ClipboardWriteRequestChild.h",
|
||||
|
@ -217,6 +219,8 @@ EXPORTS.mozilla.widget += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"ClipboardContentAnalysisChild.cpp",
|
||||
"ClipboardContentAnalysisParent.cpp",
|
||||
"ClipboardReadRequestParent.cpp",
|
||||
"ClipboardWriteRequestChild.cpp",
|
||||
"ClipboardWriteRequestParent.cpp",
|
||||
|
@ -377,6 +381,7 @@ else:
|
|||
|
||||
IPDL_SOURCES += [
|
||||
"LookAndFeelTypes.ipdlh",
|
||||
"PClipboardContentAnalysis.ipdl",
|
||||
"PClipboardReadRequest.ipdl",
|
||||
"PClipboardWriteRequest.ipdl",
|
||||
]
|
||||
|
|
|
@ -7,15 +7,19 @@
|
|||
#if defined(ACCESSIBILITY) && defined(XP_WIN)
|
||||
# include "mozilla/a11y/Compatibility.h"
|
||||
#endif
|
||||
#include "mozilla/ClipboardContentAnalysisChild.h"
|
||||
#include "mozilla/ClipboardReadRequestChild.h"
|
||||
#include "mozilla/ClipboardWriteRequestChild.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/net/CookieJarSettings.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsBaseClipboard.h"
|
||||
#include "nsIContentAnalysis.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
@ -73,8 +77,29 @@ nsClipboardProxy::GetData(nsITransferable* aTransferable,
|
|||
aTransferable->FlavorsTransferableCanImport(types);
|
||||
|
||||
IPCTransferableDataOrError transferableOrError;
|
||||
ContentChild::GetSingleton()->SendGetClipboard(
|
||||
types, aWhichClipboard, aWindowContext, &transferableOrError);
|
||||
nsCOMPtr<nsIContentAnalysis> contentAnalysis =
|
||||
mozilla::components::nsIContentAnalysis::Service();
|
||||
Unused << NS_WARN_IF(!contentAnalysis);
|
||||
bool contentAnalysisMightBeActive = false;
|
||||
if (contentAnalysis) {
|
||||
contentAnalysis->GetMightBeActive(&contentAnalysisMightBeActive);
|
||||
}
|
||||
if (MOZ_UNLIKELY(contentAnalysisMightBeActive)) {
|
||||
if (!ClipboardContentAnalysisChild::GetSingleton()) {
|
||||
if (!ContentChild::GetSingleton()->SendCreateClipboardContentAnalysis()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mozilla::SpinEventLoopUntil(
|
||||
"Wait for ClipboardContentAnalysisChild creation"_ns,
|
||||
[] { return ClipboardContentAnalysisChild::GetSingleton(); });
|
||||
}
|
||||
ClipboardContentAnalysisChild::GetSingleton()->SendGetClipboard(
|
||||
types, aWhichClipboard, aWindowContext->InnerWindowId(),
|
||||
&transferableOrError);
|
||||
} else {
|
||||
ContentChild::GetSingleton()->SendGetClipboard(
|
||||
types, aWhichClipboard, aWindowContext, &transferableOrError);
|
||||
}
|
||||
|
||||
if (transferableOrError.type() == IPCTransferableDataOrError::Tnsresult) {
|
||||
MOZ_ASSERT(NS_FAILED(transferableOrError.get_nsresult()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче