Bug 1574307 - Part 4. Notify GV of viewport-fit. r=geckoview-reviewers,snorp

`viewport-fit` is hint that browser application can use cutout area. So we should expose it to GeckoView application to set `layoutInDisplayCutoutMode`.

When meta element is found or changed, `ContentDelegate.onMetaviewportFitChange` is called. Even if nothing, it will be called after DOMContentLoaded is fired.

Depends on D57398

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Makoto Kato 2020-01-20 08:42:05 +00:00
Родитель 7b3ef75994
Коммит 452a87b7b0
6 изменённых файлов: 83 добавлений и 2 удалений

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

@ -39,6 +39,8 @@ class GeckoViewContentChild extends GeckoViewChildModule {
});
this.timeoutsSuspended = false;
this.lastViewportFit = "";
this.triggerViewportFitChange = null;
this.messageManager.addMessageListener(
"GeckoView:DOMFullscreenEntered",
@ -80,6 +82,7 @@ class GeckoViewContentChild extends GeckoViewChildModule {
addEventListener("contextmenu", this, { capture: true });
addEventListener("DOMContentLoaded", this, false);
addEventListener("MozFirstContentfulPaint", this, false);
addEventListener("DOMMetaViewportFitChanged", this, false);
}
onDisable() {
@ -94,6 +97,7 @@ class GeckoViewContentChild extends GeckoViewChildModule {
removeEventListener("contextmenu", this, { capture: true });
removeEventListener("DOMContentLoaded", this);
removeEventListener("MozFirstContentfulPaint", this);
removeEventListener("DOMMetaViewportFitChanged", this);
}
toPixels(aLength, aType) {
@ -124,6 +128,24 @@ class GeckoViewContentChild extends GeckoViewChildModule {
return content.windowUtils.SCROLL_MODE_SMOOTH;
}
notifyParentOfViewportFit() {
if (this.triggerViewportFitChange) {
content.cancelIdleCallback(this.triggerViewportFitChange);
}
this.triggerViewportFitChange = content.requestIdleCallback(() => {
this.triggerViewportFitChange = null;
let viewportFit = content.windowUtils.getViewportFitInfo();
if (this.lastViewportFit === viewportFit) {
return;
}
this.lastViewportFit = viewportFit;
this.eventDispatcher.sendRequest({
type: "GeckoView:DOMMetaViewportFit",
viewportfit: viewportFit,
});
});
}
receiveMessage(aMsg) {
debug`receiveMessage: ${aMsg.name}`;
@ -271,6 +293,11 @@ class GeckoViewContentChild extends GeckoViewChildModule {
content.windowUtils.resumeTimeouts();
this.timeoutsSuspended = false;
}
if (aMsg.data.active) {
// Send current viewport-fit to parent.
this.lastViewportFit = "";
this.notifyParentOfViewportFit();
}
}
if (content && aMsg.data.suspendMedia) {
content.windowUtils.mediaSuspend = aMsg.data.active
@ -380,6 +407,11 @@ class GeckoViewContentChild extends GeckoViewChildModule {
case "MozDOMFullscreen:Exit":
sendAsyncMessage("GeckoView:DOMFullscreenExit");
break;
case "DOMMetaViewportFitChanged":
if (aEvent.originalTarget.ownerGlobal == content) {
this.notifyParentOfViewportFit();
}
break;
case "DOMTitleChanged":
this.eventDispatcher.sendRequest({
type: "GeckoView:DOMTitleChanged",
@ -408,6 +440,11 @@ class GeckoViewContentChild extends GeckoViewChildModule {
}
break;
case "DOMContentLoaded": {
if (aEvent.originalTarget.ownerGlobal == content) {
// If loaded content doesn't have viewport-fit, parent still
// uses old value of previous content.
this.notifyParentOfViewportFit();
}
content.requestIdleCallback(async () => {
const manifest = await ManifestObtainer.contentObtainManifest(
content

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

@ -687,6 +687,7 @@ package org.mozilla.geckoview {
method @UiThread default public void onFocusRequest(@NonNull GeckoSession);
method @UiThread default public void onFullScreen(@NonNull GeckoSession, boolean);
method @UiThread default public void onKill(@NonNull GeckoSession);
method @UiThread default public void onMetaViewportFitChange(@NonNull GeckoSession, @NonNull String);
method @UiThread @Nullable default public GeckoResult<SlowScriptResponse> onSlowScript(@NonNull GeckoSession, @NonNull String);
method @UiThread default public void onTitleChange(@NonNull GeckoSession, @Nullable String);
method @UiThread default public void onWebAppManifest(@NonNull GeckoSession, @NonNull JSONObject);

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

@ -1,7 +1,7 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<style type="text/css">
#wide {
background-color: rgb(200, 0, 0);

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

@ -327,6 +327,33 @@ class ContentDelegateTest : BaseSessionTest() {
})
}
@Test fun viewportFit() {
mainSession.loadTestPath(VIEWPORT_PATH)
mainSession.waitUntilCalled(object : Callbacks.All {
@AssertCalled(count = 1)
override fun onPageStop(session: GeckoSession, success: Boolean) {
assertThat("Page load should succeed", success, equalTo(true))
}
@AssertCalled(count = 1)
override fun onMetaViewportFitChange(session: GeckoSession, viewportFit: String) {
assertThat("viewport-fit should match", viewportFit, equalTo("cover"))
}
})
mainSession.loadTestPath(HELLO_HTML_PATH)
mainSession.waitUntilCalled(object : Callbacks.All {
@AssertCalled(count = 1)
override fun onPageStop(session: GeckoSession, success: Boolean) {
assertThat("Page load should succeed", success, equalTo(true))
}
@AssertCalled(count = 1)
override fun onMetaViewportFitChange(session: GeckoSession, viewportFit: String) {
assertThat("viewport-fit should match", viewportFit, equalTo("auto"))
}
})
}
/**
* Preferences to induce wanted behaviour.

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

@ -423,6 +423,7 @@ public class GeckoSession implements Parcelable {
"GeckoView:ContentCrash",
"GeckoView:ContentKill",
"GeckoView:ContextMenu",
"GeckoView:DOMMetaViewportFit",
"GeckoView:DOMTitleChanged",
"GeckoView:DOMWindowClose",
"GeckoView:ExternalResponse",
@ -459,6 +460,9 @@ public class GeckoSession implements Parcelable {
message.getInt("screenY"),
elem);
} else if ("GeckoView:DOMMetaViewportFit".equals(event)) {
delegate.onMetaViewportFitChange(GeckoSession.this,
message.getString("viewportfit"));
} else if ("GeckoView:DOMTitleChanged".equals(event)) {
delegate.onTitleChange(GeckoSession.this,
message.getString("title"));
@ -3014,6 +3018,16 @@ public class GeckoSession implements Parcelable {
@UiThread
default void onFullScreen(@NonNull GeckoSession session, boolean fullScreen) {}
/**
* A viewport-fit was discovered in the content or updated after the content.
*
* @param session The GeckoSession that initiated the callback.
* @param viewportFit The value of viewport-fit of meta element in content.
* @see <a href="https://drafts.csswg.org/css-round-display/#viewport-fit-descriptor">4.1. The viewport-fit descriptor</a>
*/
@UiThread
default void onMetaViewportFitChange(@NonNull GeckoSession session, @NonNull String viewportFit) {}
/**
* Element details for onContextMenu callbacks.
*/

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

@ -33,6 +33,7 @@ exclude: true
exceptions and to add better support for removing exceptions. This deprecates [`ExceptionList`][74.8]
and [`restoreExceptionList`][74.9] with the intent to remove them in 76.
([bug 1587552]({{bugzilla}}1587552))
- Added [`GeckoSession.ContentDelegate.onMetaViewportFitChange`][74.10]. This exposes `viewport-fit` value that is CSS Round Display Level 1. ([bug 1574307]({{bugzilla}}1574307))
[74.1]: {{javadoc_uri}}/WebExtensionController.html#enable-org.mozilla.geckoview.WebExtension-int-
[74.2]: {{javadoc_uri}}/WebExtensionController.html#disable-org.mozilla.geckoview.WebExtension-int-
@ -43,6 +44,7 @@ exclude: true
[74.7]: {{javadoc_uri}}/ContentBlockingController.html
[74.8]: {{javadoc_uri}}/ContentBlockingController.ExceptionList.html
[74.9]: {{javadoc_uri}}/ContentBlockingController.html#restoreExceptionList-org.mozilla.geckoview.ContentBlockingController.ExceptionList-
[74.10]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onMetaViewportFitChange-org.mozilla.geckoview.GeckoSession-java.lang.String-
## v73
- Added [`WebExtensionController.install`][73.1] and [`uninstall`][73.2] to
@ -553,4 +555,4 @@ exclude: true
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
[65.25]: {{javadoc_uri}}/GeckoResult.html
[api-version]: e89f3bb79d0c5cc936812de4c2d8f4d30923afb9
[api-version]: 5342560e4c467a1f3d363748ebb20a077d2e8385