Bug 1500257 part 5 - Implement messages for loading and displaying remote subframes on PRemoteFrame. r=qdot

This commit hooks up the pieces of the PRemoteFrame protocol that
will proxy initialization, sizing, and display messages. The messages
chosen are just enough to start the frame and get an initial rendering.

Differential Revision: https://phabricator.services.mozilla.com/D17445

--HG--
extra : source : b68b732411e2e1e6851799262246bff70e6649da
extra : intermediate-source : c19bc81c4f43a5adba92184b2572c09c6c5a0680
This commit is contained in:
Ryan Hunt 2019-01-23 11:04:26 -06:00
Родитель 0d69472e8b
Коммит f83e394596
7 изменённых файлов: 159 добавлений и 11 удалений

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

@ -356,8 +356,14 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() {
return NS_ERROR_FAILURE;
}
// FIXME get error codes from child
mRemoteBrowser->LoadURL(mURIToLoad);
if (mRemoteFrameChild) {
nsAutoCString spec;
mURIToLoad->GetSpec(spec);
Unused << mRemoteFrameChild->SendLoadURL(spec);
} else {
// FIXME get error codes from child
mRemoteBrowser->LoadURL(mURIToLoad);
}
if (!mRemoteBrowserShown) {
// This can fail if it's too early to show the frame, we will retry later.
@ -811,12 +817,25 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
return false;
}
RenderFrame* rf = GetCurrentRenderFrame();
if (!rf) {
return false;
if (mRemoteFrameChild) {
nsCOMPtr<nsISupports> container =
mOwnerContent->OwnerDoc()->GetContainer();
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
nsCOMPtr<nsIWidget> mainWidget;
baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
nsSizeMode sizeMode =
mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
Unused << mRemoteFrameChild->SendShow(
size, ParentWindowIsActive(mOwnerContent->OwnerDoc()), sizeMode);
mRemoteBrowserShown = true;
return true;
}
if (!rf->AttachLayerManager()) {
RenderFrame* rf =
mRemoteBrowser ? mRemoteBrowser->GetRenderFrame() : nullptr;
if (!rf || !rf->AttachLayerManager()) {
// This is just not going to work.
return false;
}
@ -834,7 +853,11 @@ bool nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
// Don't show remote iframe if we are waiting for the completion of reflow.
if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
mRemoteBrowser->UpdateDimensions(dimensions, size);
if (mRemoteBrowser) {
mRemoteBrowser->UpdateDimensions(dimensions, size);
} else if (mRemoteFrameChild) {
mRemoteFrameChild->UpdateDimensions(dimensions, size);
}
}
}
@ -923,6 +946,11 @@ nsresult nsFrameLoader::SwapWithOtherRemoteLoader(
return NS_ERROR_NOT_IMPLEMENTED;
}
// FIXME: Consider supporting FrameLoader swapping for remote sub frames.
if (mRemoteFrameChild) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (!mRemoteBrowser || !aOther->mRemoteBrowser) {
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -2270,7 +2298,7 @@ nsresult nsFrameLoader::GetWindowDimensions(nsIntRect& aRect) {
nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
if (IsRemoteFrame()) {
if (mRemoteBrowser) {
if (mRemoteBrowser || mRemoteFrameChild) {
ScreenIntSize size = aIFrame->GetSubdocumentSize();
// If we were not able to show remote frame before, we should probably
// retry now to send correct showInfo.
@ -2280,7 +2308,11 @@ nsresult nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame* aIFrame) {
nsIntRect dimensions;
NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
mLazySize = size;
mRemoteBrowser->UpdateDimensions(dimensions, size);
if (mRemoteBrowser) {
mRemoteBrowser->UpdateDimensions(dimensions, size);
} else if (mRemoteFrameChild) {
mRemoteFrameChild->UpdateDimensions(dimensions, size);
}
}
return NS_OK;
}

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

@ -8,6 +8,11 @@ include protocol PBrowser;
include DOMTypes;
using ScreenIntSize from "Units.h";
using nsSizeMode from "nsIWidgetListener.h";
using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
namespace mozilla {
namespace dom {
@ -16,9 +21,21 @@ namespace dom {
*/
async protocol PRemoteFrame {
manager PBrowser;
child:
async SetLayersId(LayersId layersId);
parent:
// Destroy the remote web browser due to the nsFrameLoader going away.
async __delete__();
// DocShell messaging.
async LoadURL(nsCString aSpec);
// Out of process rendering.
async Show(ScreenIntSize size, bool parentIsActive, nsSizeMode sizeMode);
async UpdateDimensions(DimensionInfo dimensions) compressall;
async RenderLayers(bool aEnabled, bool aForceRepaint, LayersObserverEpoch aEpoch);
};
} // namespace dom

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

@ -41,6 +41,45 @@ already_AddRefed<RemoteFrameChild> RemoteFrameChild::Create(
return remoteFrame.forget();
}
void RemoteFrameChild::UpdateDimensions(const nsIntRect& aRect,
const mozilla::ScreenIntSize& aSize) {
MOZ_DIAGNOSTIC_ASSERT(mIPCOpen);
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(owner);
if (!widget) {
widget = nsContentUtils::WidgetForDocument(owner->OwnerDoc());
}
MOZ_DIAGNOSTIC_ASSERT(widget);
CSSToLayoutDeviceScale widgetScale = widget->GetDefaultScale();
LayoutDeviceIntRect devicePixelRect = ViewAs<LayoutDevicePixel>(
aRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
LayoutDeviceIntSize devicePixelSize = ViewAs<LayoutDevicePixel>(
aSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
// XXX What are clientOffset and chromeOffset used for? Are they meaningful
// for nested iframes with transforms?
LayoutDeviceIntPoint clientOffset;
LayoutDeviceIntPoint chromeOffset;
CSSRect unscaledRect = devicePixelRect / widgetScale;
CSSSize unscaledSize = devicePixelSize / widgetScale;
hal::ScreenOrientation orientation = hal::eScreenOrientation_Default;
DimensionInfo di(unscaledRect, unscaledSize, orientation, clientOffset,
chromeOffset);
Unused << SendUpdateDimensions(di);
}
IPCResult RemoteFrameChild::RecvSetLayersId(
const mozilla::layers::LayersId& aLayersId) {
MOZ_ASSERT(!mLayersId.IsValid() && aLayersId.IsValid());
mLayersId = aLayersId;
return IPC_OK();
}
void RemoteFrameChild::ActorDestroy(ActorDestroyReason aWhy) {
mIPCOpen = false;
}

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

@ -30,7 +30,16 @@ class RemoteFrameChild : public PRemoteFrameChild {
static already_AddRefed<RemoteFrameChild> Create(nsFrameLoader* aFrameLoader,
const TabContext& aContext,
const nsString& aRemoteType);
void UpdateDimensions(const nsIntRect& aRect,
const mozilla::ScreenIntSize& aSize);
protected:
friend class PRemoteFrameChild;
mozilla::ipc::IPCResult RecvSetLayersId(
const mozilla::layers::LayersId& aLayersId);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:

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

@ -69,9 +69,48 @@ nsresult RemoteFrameParent::Init(const nsString& aPresentationURL,
mTabParent->SetOwnerElement(Manager()->GetOwnerElement());
mTabParent->InitRendering();
RenderFrame* rf = mTabParent->GetRenderFrame();
if (NS_WARN_IF(!rf)) {
MOZ_ASSERT(false, "No RenderFrame");
return NS_ERROR_FAILURE;
}
// Send the newly created layers ID back into content.
Unused << SendSetLayersId(rf->GetLayersId());
return NS_OK;
}
IPCResult RemoteFrameParent::RecvShow(const ScreenIntSize& aSize,
const bool& aParentIsActive,
const nsSizeMode& aSizeMode) {
RenderFrame* rf = mTabParent->GetRenderFrame();
if (!rf->AttachLayerManager()) {
MOZ_CRASH();
}
Unused << mTabParent->SendShow(aSize, mTabParent->GetShowInfo(),
aParentIsActive, aSizeMode);
return IPC_OK();
}
IPCResult RemoteFrameParent::RecvLoadURL(const nsCString& aUrl) {
Unused << mTabParent->SendLoadURL(aUrl, mTabParent->GetShowInfo());
return IPC_OK();
}
IPCResult RemoteFrameParent::RecvUpdateDimensions(
const DimensionInfo& aDimensions) {
Unused << mTabParent->SendUpdateDimensions(aDimensions);
return IPC_OK();
}
IPCResult RemoteFrameParent::RecvRenderLayers(
const bool& aEnabled, const bool& aForceRepaint,
const layers::LayersObserverEpoch& aEpoch) {
Unused << mTabParent->SendRenderLayers(aEnabled, aForceRepaint, aEpoch);
return IPC_OK();
}
void RemoteFrameParent::ActorDestroy(ActorDestroyReason aWhy) {
mIPCOpen = false;
}

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

@ -31,6 +31,18 @@ class RemoteFrameParent : public PRemoteFrameParent {
}
protected:
friend class PRemoteFrameParent;
mozilla::ipc::IPCResult RecvShow(const ScreenIntSize& aSize,
const bool& aParentIsActive,
const nsSizeMode& aSizeMode);
mozilla::ipc::IPCResult RecvLoadURL(const nsCString& aUrl);
mozilla::ipc::IPCResult RecvUpdateDimensions(
const DimensionInfo& aDimensions);
mozilla::ipc::IPCResult RecvRenderLayers(const bool& aEnabled,
const bool& aForceRepaint,
const LayersObserverEpoch& aEpoch);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:

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

@ -558,6 +558,8 @@ class TabParent final : public PBrowserParent,
void NavigateByKey(bool aForward, bool aForDocumentNavigation);
ShowInfo GetShowInfo();
protected:
bool ReceiveMessage(
const nsString& aMessage, bool aSync, ipc::StructuredCloneData* aData,
@ -726,8 +728,6 @@ class TabParent final : public PBrowserParent,
int32_t mActiveSupressDisplayportCount;
#endif
ShowInfo GetShowInfo();
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.