mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1695806 - Defer sending a snapshot reqeust for remote process iframe until cloning the iframe document finished. r=mattwoodrow,nika
Differential Revision: https://phabricator.services.mozilla.com/D119950
This commit is contained in:
parent
139b694208
commit
a5ecf77776
@ -14,6 +14,7 @@
|
||||
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/dom/PBackgroundSessionStorageCache.h"
|
||||
#include "mozilla/dom/PWindowGlobalParent.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
@ -2511,6 +2512,45 @@ void CanonicalBrowsingContext::SetTouchEventsOverride(
|
||||
SetTouchEventsOverrideInternal(aOverride, aRv);
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::CloneDocumentTreeInto(
|
||||
CanonicalBrowsingContext* aSource, const nsACString& aRemoteType,
|
||||
embedding::PrintData&& aPrintData) {
|
||||
RemotenessChangeOptions options;
|
||||
options.mRemoteType = aRemoteType;
|
||||
|
||||
mClonePromise =
|
||||
ChangeRemoteness(options, /* aPendingSwitchId = */ 0)
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[source = MaybeDiscardedBrowsingContext{aSource},
|
||||
data = std::move(aPrintData)](
|
||||
BrowserParent* aBp) -> RefPtr<GenericNonExclusivePromise> {
|
||||
return aBp->SendCloneDocumentTreeIntoSelf(source, data)
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[](BrowserParent::CloneDocumentTreeIntoSelfPromise::
|
||||
ResolveOrRejectValue&& aValue) {
|
||||
if (aValue.IsResolve() && aValue.ResolveValue()) {
|
||||
return GenericNonExclusivePromise::CreateAndResolve(
|
||||
true, __func__);
|
||||
}
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
});
|
||||
},
|
||||
[](nsresult aRv) -> RefPtr<GenericNonExclusivePromise> {
|
||||
NS_WARNING(
|
||||
nsPrintfCString("Remote clone failed: %x\n", unsigned(aRv))
|
||||
.get());
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
});
|
||||
|
||||
mClonePromise->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self = RefPtr{this}]() { self->mClonePromise = nullptr; });
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(CanonicalBrowsingContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CanonicalBrowsingContext,
|
||||
|
@ -36,6 +36,10 @@ class nsITimer;
|
||||
namespace mozilla {
|
||||
enum class CallState;
|
||||
|
||||
namespace embedding {
|
||||
class PrintData;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class DocumentLoadListener;
|
||||
}
|
||||
@ -331,6 +335,16 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
void ClearPermanentKey() { mPermanentKey.setNull(); }
|
||||
void MaybeSetPermanentKey(Element* aEmbedder);
|
||||
|
||||
void CloneDocumentTreeInto(CanonicalBrowsingContext* aSource,
|
||||
const nsACString& aRemoteType,
|
||||
embedding::PrintData&& aPrintData);
|
||||
|
||||
// Returns a Promise which resolves when cloning documents for printing
|
||||
// finished if this browsing context is cloning document tree.
|
||||
RefPtr<GenericNonExclusivePromise> GetClonePromise() const {
|
||||
return mClonePromise;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Called when the browsing context is being discarded.
|
||||
void CanonicalDiscard();
|
||||
@ -494,6 +508,9 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
|
||||
bool mIsReplaced = false;
|
||||
|
||||
// A Promise created when cloning documents for printing.
|
||||
RefPtr<GenericNonExclusivePromise> mClonePromise;
|
||||
|
||||
JS::Heap<JS::Value> mPermanentKey;
|
||||
};
|
||||
|
||||
|
@ -3844,20 +3844,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCloneDocumentTreeInto(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RemotenessChangeOptions options;
|
||||
options.mRemoteType = cp->GetRemoteType();
|
||||
target->ChangeRemoteness(options, /* aPendingSwitchId = */ 0)
|
||||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[source = RefPtr{source},
|
||||
data = std::move(aPrintData)](BrowserParent* aBp) {
|
||||
Unused << aBp->SendCloneDocumentTreeIntoSelf(source, data);
|
||||
},
|
||||
[](nsresult aRv) {
|
||||
NS_WARNING(
|
||||
nsPrintfCString("Remote clone failed: %x\n", unsigned(aRv))
|
||||
.get());
|
||||
});
|
||||
target->CloneDocumentTreeInto(source, cp->GetRemoteType(),
|
||||
std::move(aPrintData));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "CrossProcessPaint.h"
|
||||
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/ContentProcessManager.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
@ -357,7 +358,7 @@ void CrossProcessPaint::QueueDependencies(
|
||||
for (const auto& key : aDependencies) {
|
||||
auto dependency = dom::TabId(key);
|
||||
|
||||
// Get the current WindowGlobalParent of the remote browser that was marked
|
||||
// Get the current BrowserParent of the remote browser that was marked
|
||||
// as a dependency
|
||||
dom::ContentProcessManager* cpm =
|
||||
dom::ContentProcessManager::GetSingleton();
|
||||
@ -370,17 +371,11 @@ void CrossProcessPaint::QueueDependencies(
|
||||
(uint64_t)dependency);
|
||||
continue;
|
||||
}
|
||||
RefPtr<dom::WindowGlobalParent> wgp =
|
||||
browser->GetBrowsingContext()->GetCurrentWindowGlobal();
|
||||
|
||||
if (!wgp) {
|
||||
CPP_LOG("Skipping dependency %" PRIu64 " with no current WGP.\n",
|
||||
(uint64_t)dependency);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Apply some sort of clipping to visible bounds here (Bug 1562720)
|
||||
QueuePaint(wgp, Nothing());
|
||||
// Note that if the remote document is currently being cloned, it's possible
|
||||
// that the BrowserParent isn't the one for the cloned document, but the
|
||||
// BrowsingContext should be persisted/consistent.
|
||||
QueuePaint(browser->GetBrowsingContext());
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,13 +385,49 @@ void CrossProcessPaint::QueuePaint(dom::WindowGlobalParent* aWGP,
|
||||
CrossProcessPaintFlags aFlags) {
|
||||
MOZ_ASSERT(!mReceivedFragments.Contains(GetTabId(aWGP)));
|
||||
|
||||
CPP_LOG("Queueing paint for %p.\n", aWGP);
|
||||
CPP_LOG("Queueing paint for WindowGlobalParent(%p).\n", aWGP);
|
||||
|
||||
aWGP->DrawSnapshotInternal(this, aRect, mScale, aBackgroundColor,
|
||||
(uint32_t)aFlags);
|
||||
mPendingFragments += 1;
|
||||
}
|
||||
|
||||
void CrossProcessPaint::QueuePaint(dom::CanonicalBrowsingContext* aBc) {
|
||||
RefPtr<GenericNonExclusivePromise> clonePromise = aBc->GetClonePromise();
|
||||
|
||||
if (!clonePromise) {
|
||||
RefPtr<dom::WindowGlobalParent> wgp = aBc->GetCurrentWindowGlobal();
|
||||
// TODO: Apply some sort of clipping to visible bounds here (Bug 1562720)
|
||||
QueuePaint(wgp, Nothing(), NS_RGBA(0, 0, 0, 0),
|
||||
CrossProcessPaintFlags::DrawView);
|
||||
return;
|
||||
}
|
||||
|
||||
CPP_LOG("Queueing paint for BrowsingContext(%p).\n", aBc);
|
||||
// In the case it's still in the process of cloning the remote document, we
|
||||
// should defer the snapshot request after the cloning has been finished.
|
||||
mPendingFragments += 1;
|
||||
clonePromise->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self = RefPtr{this}, bc = RefPtr{aBc}]() {
|
||||
RefPtr<dom::WindowGlobalParent> wgp = bc->GetCurrentWindowGlobal();
|
||||
MOZ_ASSERT(!self->mReceivedFragments.Contains(GetTabId(wgp)));
|
||||
|
||||
// TODO: Apply some sort of clipping to visible bounds here (Bug
|
||||
// 1562720)
|
||||
wgp->DrawSnapshotInternal(self, Nothing(), self->mScale,
|
||||
NS_RGBA(0, 0, 0, 0),
|
||||
(uint32_t)CrossProcessPaintFlags::DrawView);
|
||||
},
|
||||
[self = RefPtr{this}]() {
|
||||
CPP_LOG(
|
||||
"Abort painting for BrowsingContext(%p) because cloning remote "
|
||||
"document failed.\n",
|
||||
self.get());
|
||||
self->Clear(NS_ERROR_FAILURE);
|
||||
});
|
||||
}
|
||||
|
||||
void CrossProcessPaint::Clear(nsresult aStatus) {
|
||||
mPendingFragments = 0;
|
||||
mReceivedFragments.Clear();
|
||||
|
@ -30,6 +30,7 @@ struct ParamTraits;
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class CanonicalBrowsingContext;
|
||||
class DOMRect;
|
||||
class Promise;
|
||||
class WindowGlobalParent;
|
||||
@ -145,6 +146,8 @@ class CrossProcessPaint final {
|
||||
nscolor aBackgroundColor = NS_RGBA(0, 0, 0, 0),
|
||||
CrossProcessPaintFlags aFlags = CrossProcessPaintFlags::DrawView);
|
||||
|
||||
void QueuePaint(dom::CanonicalBrowsingContext* aBc);
|
||||
|
||||
/// Clear the state of this paint so that it cannot be resolved or receive
|
||||
/// any paint fragments.
|
||||
void Clear(nsresult aStatus);
|
||||
|
@ -1,9 +0,0 @@
|
||||
[iframe-cross-origin-print.sub.html]
|
||||
bug:
|
||||
if fission: https://bugzilla.mozilla.org/show_bug.cgi?id=1695806
|
||||
expected:
|
||||
if fission and (os == "linux") and not debug and not webrender: [FAIL, PASS]
|
||||
if fission and (os == "linux") and not debug and webrender: [PASS, FAIL]
|
||||
if fission and (os == "linux") and debug: [FAIL, PASS]
|
||||
if fission and (os == "win") and not debug: [PASS, FAIL]
|
||||
if fission and (os == "win") and debug: [FAIL, PASS]
|
Loading…
Reference in New Issue
Block a user