зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1647797 - Add GeckoView API to listen for when contentful paint status has been reset. r=geckoview-reviewers,agi,esawin
Android-components listens to the GeckoView callback onFirstContentfulPaint to track whether a contentful paint has occured, in order to decide when to thumbnail a tab. Currently this gets fired once per tab. However, when the GeckoSession is paused, we clear cached resources in the compositor. This means that when the session is resumed, the compositor does not have the necessary information to render the page (such as painted content buffers, or the webrender display list). Because android-components attempts to capture a new thumbnail immediately upon resuming, it ends up capturing a blank thumbnail. To fix this, add a new callback onPaintStatusReset() which is invoked when the cached resources are cleared. Android-components can listen for this to be informed when the contentful paint is no longer visible. It can then wait until the subsequent contentful paint occurs before capturing the thumbnail. Differential Revision: https://phabricator.services.mozilla.com/D87341
This commit is contained in:
Родитель
f5c045a279
Коммит
54ed855193
|
@ -2982,6 +2982,13 @@ void BrowserChild::ClearCachedResources() {
|
|||
MOZ_ASSERT(lm);
|
||||
|
||||
lm->ClearCachedResources();
|
||||
|
||||
if (nsCOMPtr<Document> document = GetTopLevelDocument()) {
|
||||
nsPresContext* presContext = document->GetPresContext();
|
||||
if (presContext) {
|
||||
presContext->NotifyPaintStatusReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserChild::InvalidateLayers() {
|
||||
|
|
|
@ -2366,6 +2366,16 @@ void nsPresContext::NotifyContentfulPaint() {
|
|||
}
|
||||
}
|
||||
|
||||
void nsPresContext::NotifyPaintStatusReset() {
|
||||
mHadNonBlankPaint = false;
|
||||
mHadContentfulPaint = false;
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
(new AsyncEventDispatcher(mDocument, u"MozPaintStatusReset"_ns,
|
||||
CanBubble::eYes, ChromeOnlyDispatch::eYes))
|
||||
->PostDOMEvent();
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsPresContext::NotifyDOMContentFlushed() {
|
||||
NS_ENSURE_TRUE_VOID(mPresShell);
|
||||
if (IsRootContentDocument()) {
|
||||
|
|
|
@ -1032,6 +1032,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||
bool HadContentfulPaint() const { return mHadContentfulPaint; }
|
||||
void NotifyNonBlankPaint();
|
||||
void NotifyContentfulPaint();
|
||||
void NotifyPaintStatusReset();
|
||||
void NotifyDOMContentFlushed();
|
||||
|
||||
bool UsesExChUnits() const { return mUsesExChUnits; }
|
||||
|
|
|
@ -163,6 +163,12 @@ class ContentDelegateChild extends GeckoViewActorChild {
|
|||
});
|
||||
break;
|
||||
}
|
||||
case "MozPaintStatusReset": {
|
||||
this.eventDispatcher.sendRequest({
|
||||
type: "GeckoView:PaintStatusReset",
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -571,6 +571,7 @@ function startup() {
|
|||
"MozDOMFullscreen:Exited": {},
|
||||
"MozDOMFullscreen:Request": {},
|
||||
MozFirstContentfulPaint: {},
|
||||
MozPaintStatusReset: {},
|
||||
contextmenu: { capture: true },
|
||||
},
|
||||
allFrames: true,
|
||||
|
|
|
@ -748,6 +748,7 @@ package org.mozilla.geckoview {
|
|||
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 default public void onPaintStatusReset(@NonNull GeckoSession);
|
||||
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);
|
||||
|
|
|
@ -356,6 +356,7 @@ public class GeckoSession implements Parcelable {
|
|||
"GeckoView:FullScreenExit",
|
||||
"GeckoView:WebAppManifest",
|
||||
"GeckoView:FirstContentfulPaint",
|
||||
"GeckoView:PaintStatusReset",
|
||||
}
|
||||
) {
|
||||
@Override
|
||||
|
@ -413,6 +414,8 @@ public class GeckoSession implements Parcelable {
|
|||
}
|
||||
} else if ("GeckoView:FirstContentfulPaint".equals(event)) {
|
||||
delegate.onFirstContentfulPaint(GeckoSession.this);
|
||||
} else if ("GeckoView:PaintStatusReset".equals(event)) {
|
||||
delegate.onPaintStatusReset(GeckoSession.this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -3334,9 +3337,10 @@ public class GeckoSession implements Parcelable {
|
|||
/**
|
||||
* 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.
|
||||
* a page has been loaded, or after a {@link #onPaintStatusReset(GeckoSession)}
|
||||
* event. 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.
|
||||
|
@ -3345,6 +3349,21 @@ public class GeckoSession implements Parcelable {
|
|||
@UiThread
|
||||
default void onFirstContentfulPaint(@NonNull GeckoSession session) {}
|
||||
|
||||
/**
|
||||
* Notification that the paint status has been reset.
|
||||
*
|
||||
* This callback is invoked whenever the painted content is no longer being
|
||||
* displayed. This can occur in response to the session being paused.
|
||||
* After this has fired the compositor may continue rendering, but may not
|
||||
* render the page content. This callback can therefore be used in conjunction
|
||||
* with {@link #onFirstContentfulPaint(GeckoSession)} to determine when there is
|
||||
* valid content being rendered.
|
||||
*
|
||||
* @param session The GeckoSession that had the paint status reset event.
|
||||
*/
|
||||
@UiThread
|
||||
default void onPaintStatusReset(@NonNull GeckoSession session) {}
|
||||
|
||||
/**
|
||||
* This is fired when the loaded document has a valid Web App Manifest present.
|
||||
*
|
||||
|
|
|
@ -16,9 +16,13 @@ exclude: true
|
|||
## v81
|
||||
- Added `cookiePurging` to [`ContentBlocking.Settings.Builder`][81.1] and `getCookiePurging` and `setCookiePurging`
|
||||
to [`ContentBlocking.Settings`][81.2].
|
||||
- Added [`GeckoSession.ContentDelegate.onPaintStatusReset()`][81.3] callback which notifies when valid content is no longer being rendered.
|
||||
- Made [`GeckoSession.ContentDelegate.onFirstContentfulPaint()`][81.4] additionally be called for the first contentful paint following a `onPaintStatusReset()` event, rather than just the first contentful paint of the session.
|
||||
|
||||
[81.1]: {{javadoc_uri}}/ContentBlocking.Settings.Builder.html
|
||||
[81.2]: {{javadoc_uri}}/ContentBlocking.Settings.html
|
||||
[81.3]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onPaintStatusReset-org.mozilla.geckoview.GeckoSession-
|
||||
[81.4]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onFirstContentfulPaint-org.mozilla.geckoview.GeckoSession-
|
||||
|
||||
## v80
|
||||
- Removed `GeckoSession.hashCode` and `GeckoSession.equals` overrides in favor
|
||||
|
@ -761,4 +765,4 @@ to allow adding gecko profiler markers.
|
|||
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
|
||||
[65.25]: {{javadoc_uri}}/GeckoResult.html
|
||||
|
||||
[api-version]: a3245a37268efa5b1bbf787a3aca046670d36cdb
|
||||
[api-version]: 9f4bf24e0795c8da7caf58487e659918ea1a56cc
|
||||
|
|
Загрузка…
Ссылка в новой задаче