Bug 1766082: Allow content to wait for parent screen transforms r=emilio

Content processes can provide screen coordinates in e.g. window objects and events without waiting for the proper client-to-screen transforms to be given to them from the parent process.  This poses a problem for tests that want to check the screen coordinates, so we add SpecialPowers.ContentTransformsReceived() to allow content processes to wait for these transforms.

Differential Revision: https://phabricator.services.mozilla.com/D144742
This commit is contained in:
David Parks 2022-05-02 20:43:12 +00:00
Родитель 3065034574
Коммит 030a726af8
4 изменённых файлов: 53 добавлений и 0 удалений

Просмотреть файл

@ -27,6 +27,12 @@ interface nsIBrowserChild : nsISupports
void remoteDropLinks(in Array<nsIDroppedLinkItem> links);
/**
* Resolved after content has received a PBrowser::ChildToParentMatrix.
*/
[implicit_jscontext]
Promise contentTransformsReceived();
readonly attribute uint64_t tabId;
/*

Просмотреть файл

@ -539,6 +539,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowserChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebNav)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStoreChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContentTransformPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -548,6 +549,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowserChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebNav)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSessionStoreChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentTransformPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(BrowserChild)
@ -1300,6 +1302,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvChildToParentMatrix(
mTopLevelViewportVisibleRectInBrowserCoords =
aTopLevelViewportVisibleRectInBrowserCoords;
if (mContentTransformPromise) {
mContentTransformPromise->MaybeResolveWithUndefined();
mContentTransformPromise = nullptr;
}
// Trigger an intersection observation update since ancestor viewports
// changed.
if (RefPtr<Document> toplevelDoc = GetTopLevelDocument()) {
@ -3849,6 +3856,28 @@ void BrowserChild::NotifyContentBlockingEvent(
}
}
NS_IMETHODIMP
BrowserChild::ContentTransformsReceived(JSContext* aCx,
dom::Promise** aPromise) {
auto* globalObject = xpc::CurrentNativeGlobal(aCx);
ErrorResult rv;
if (mChildToParentConversionMatrix) {
// Already received content transforms
RefPtr<Promise> promise =
Promise::CreateResolvedWithUndefined(globalObject, rv);
promise.forget(aPromise);
return rv.StealNSResult();
}
if (!mContentTransformPromise) {
mContentTransformPromise = Promise::Create(globalObject, rv);
}
MOZ_ASSERT(globalObject == mContentTransformPromise->GetGlobalObject());
NS_IF_ADDREF(*aPromise = mContentTransformPromise);
return rv.StealNSResult();
}
BrowserChildMessageManager::BrowserChildMessageManager(
BrowserChild* aBrowserChild)
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),

Просмотреть файл

@ -920,6 +920,9 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
Maybe<bool> mWindowSupportsProtectedMedia;
#endif
// If set, resolve when we receive ChildToParentMatrix.
RefPtr<dom::Promise> mContentTransformPromise;
DISALLOW_EVIL_CONSTRUCTORS(BrowserChild);
};

Просмотреть файл

@ -2248,6 +2248,21 @@ class SpecialPowersChild extends JSWindowActorChild {
wrapCallback
);
}
/* Content processes asynchronously receive child-to-parent transformations
* when they are launched. Until they are received, screen coordinates
* reported to JS are wrong. This is generally ok. It behaves as if the
* user repositioned the window. But if we want to test screen coordinates,
* we need to wait for the updated data.
*/
contentTransformsReceived(win) {
try {
// throw if win is not a remote browser.
return win.docShell.browserChild.contentTransformsReceived();
} catch (e) {
return Promise.resolve();
}
}
}
SpecialPowersChild.prototype._proxiedObservers = {