Bug 1578947 - Add onFirstContentfulPaint() to GeckoView#ContentDelegate r=geckoview-reviewers,smaug,agi,snorp

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Randall E. Barker 2019-09-18 21:37:44 +00:00
Родитель f7b60d0193
Коммит 06b876b520
6 изменённых файлов: 47 добавлений и 2 удалений

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

@ -10,6 +10,9 @@
#include "nsPresContextInlines.h"
#include "mozilla/ArrayUtils.h"
#if defined(MOZ_WIDGET_ANDROID)
# include "mozilla/AsyncEventDispatcher.h"
#endif
#include "mozilla/DebugOnly.h"
#include "mozilla/Encoding.h"
#include "mozilla/EventDispatcher.h"
@ -2361,6 +2364,11 @@ void nsPresContext::NotifyContentfulPaint() {
if (nsRootPresContext* rootPresContext = GetRootPresContext()) {
mFirstContentfulPaintTransactionId =
Some(rootPresContext->mRefreshDriver->LastTransactionId().Next());
#if defined(MOZ_WIDGET_ANDROID)
(new AsyncEventDispatcher(mDocument,
NS_LITERAL_STRING("MozFirstContentfulPaint"), CanBubble::eYes,
ChromeOnlyDispatch::eYes))->PostDOMEvent();
#endif
}
}
}

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

@ -91,6 +91,7 @@ class GeckoViewContentChild extends GeckoViewChildModule {
addEventListener("MozDOMFullscreen:Request", this, false);
addEventListener("contextmenu", this, { capture: true });
addEventListener("DOMContentLoaded", this, false);
addEventListener("MozFirstContentfulPaint", this, false);
}
onDisable() {
@ -104,6 +105,7 @@ class GeckoViewContentChild extends GeckoViewChildModule {
removeEventListener("MozDOMFullscreen:Request", this);
removeEventListener("contextmenu", this, { capture: true });
removeEventListener("DOMContentLoaded", this);
removeEventListener("MozFirstContentfulPaint", this);
}
collectSessionState() {
@ -480,7 +482,13 @@ class GeckoViewContentChild extends GeckoViewChildModule {
});
}
});
break;
}
case "MozFirstContentfulPaint":
this.eventDispatcher.sendRequest({
type: "GeckoView:FirstContentfulPaint",
});
break;
}
}

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

@ -578,6 +578,7 @@ package org.mozilla.geckoview {
method @UiThread default public void onCrash(@NonNull GeckoSession);
method @UiThread default public void onExternalResponse(@NonNull GeckoSession, @NonNull GeckoSession.WebResponseInfo);
method @UiThread default public void onFirstComposite(@NonNull GeckoSession);
method @UiThread default public void onFirstContentfulPaint(@NonNull GeckoSession);
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);

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

@ -847,6 +847,16 @@ class ContentDelegateTest : BaseSessionTest() {
mainSession.releaseDisplay(display)
}
@WithDisplay(width = 10, height = 10)
@Test fun firstContentfulPaint() {
mainSession.loadTestPath(HELLO_HTML_PATH)
sessionRule.waitUntilCalled(object : Callbacks.ContentDelegate {
@AssertCalled(count = 1)
override fun onFirstContentfulPaint(session: GeckoSession) {
}
})
}
@Test fun webAppManifest() {
mainSession.loadTestPath(HELLO_HTML_PATH)
mainSession.waitUntilCalled(object : Callbacks.All {

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

@ -453,6 +453,7 @@ public class GeckoSession implements Parcelable {
"GeckoView:FullScreenEnter",
"GeckoView:FullScreenExit",
"GeckoView:WebAppManifest",
"GeckoView:FirstContentfulPaint",
}
) {
@Override
@ -505,6 +506,8 @@ public class GeckoSession implements Parcelable {
} catch (JSONException e) {
Log.e(LOGTAG, "Failed to convert web app manifest to JSON", e);
}
} else if ("GeckoView:FirstContentfulPaint".equals(event)) {
delegate.onFirstContentfulPaint(GeckoSession.this);
}
}
};
@ -3109,6 +3112,20 @@ public class GeckoSession implements Parcelable {
@UiThread
default void onFirstComposite(@NonNull GeckoSession session) {}
/**
* Notification that the first content paint has occurred.
* This callback is invoked for the first content paint after
* a page has been loaded. The function {@link #onFirstComposite(GeckoSession)}
* will be called once the compositor has started rendering. However, it is
* possible for the compositor to start rendering before there is any content to render.
* onFirstContentfulPaint() is called once some content has been rendered. It may be nothing
* more than the page background color. It is not an indication that the whole page has
* been rendered.
* @param session The GeckoSession that had a first paint event.
*/
@UiThread
default void onFirstContentfulPaint(@NonNull GeckoSession session) {}
/**
* This is fired when the loaded document has a valid Web App Manifest present.
*

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

@ -31,7 +31,7 @@ exclude: true
([bug 1511033]({{bugzilla}}1511033))
- Added ['GeckoRuntimeSettings.Builder#aboutConfigEnabled'][71.11] to control whether or
not `about:config` should be available.
- Added [`GeckoSession.ContentDelegate.onFirstContentfulPaint()`][71.12]
[71.1]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html#onBooleanScalar-org.mozilla.geckoview.RuntimeTelemetry.Metric-
[71.2]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html#onLongScalar-org.mozilla.geckoview.RuntimeTelemetry.Metric-
[71.3]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html#onStringScalar-org.mozilla.geckoview.RuntimeTelemetry.Metric-
@ -43,6 +43,7 @@ exclude: true
[71.9]: {{javadoc_uri}}/GeckoRuntime.ServiceWorkerDelegate.html
[71.10]: {{javadoc_uri}}/GeckoRuntime#setServiceWorkerDelegate-org.mozilla.geckoview.GeckoRuntime.ServiceWorkerDelegate-
[71.11]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#aboutConfigEnabled-boolean-
[71.12]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onFirstContentfulPaint-org.mozilla.geckoview.GeckoSession-
## v70
- Added API for session context assignment
@ -365,4 +366,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]: 16e050b1d50a9909b936c740a94220eaff4115a3
[api-version]: 40441c6fcd77218d1d32b468894558141d8ccad9