Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(927)

Unified Diff: android_webview/java/src/org/chromium/android_webview/AwContents.java

Issue 831903004: [WebView] Add a new flushVisualState API to AwContents. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/java/src/org/chromium/android_webview/AwContents.java
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 3ee10deafe17e003768787f98b007027fe113eda..d8b6e51058500bd01a68bf65a49d62807f579c94 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -92,6 +92,8 @@ public class AwContents implements SmartClipProvider {
// produce little visible difference.
private static final float ZOOM_CONTROLS_EPSILON = 0.007f;
+ private static final String BLANK_URL = "about:blank";
+
/**
* WebKit hit test related data strcutre. These are used to implement
* getHitTestResult, requestFocusNodeHref, requestImageRef methods in WebView.
@@ -254,6 +256,9 @@ public class AwContents implements SmartClipProvider {
// when in this state.
private boolean mTemporarilyDetached;
+ // This flag indicates that we're currently loading BLANK_URL.
+ private boolean mIsLoadingBlank = false;
+
// True when this AwContents has been destroyed.
// Do not use directly, call isDestroyed() instead.
private boolean mIsDestroyed = false;
@@ -833,7 +838,7 @@ public class AwContents implements SmartClipProvider {
if (mWebContentsObserver != null) {
mWebContentsObserver.detachFromWebContents();
}
- mWebContentsObserver = new AwWebContentsObserver(mWebContents, mContentsClient);
+ mWebContentsObserver = new AwWebContentsObserver(mWebContents, this, mContentsClient);
}
/**
@@ -1078,6 +1083,24 @@ public class AwContents implements SmartClipProvider {
mScrollOffsetManager.computeVerticalScrollRange()));
}
+ void onPageFinished(String url) {
+ if (mIsLoadingBlank) {
+ // Waiting for onPageFinished before flashing ensures that the DOM tree
+ // does not contain stale content.
+ flushVisualState(new VisualStateFlushCallback() {
+ @Override
+ public void onFailure(int reason) {
+ mIsLoadingBlank = false;
+ }
+
+ @Override
+ public void onComplete() {
+ mIsLoadingBlank = false;
+ }
+ });
+ }
+ }
+
public void clearView() {
if (!isDestroyed()) nativeClearView(mNativeAwContents);
}
@@ -1142,6 +1165,17 @@ public class AwContents implements SmartClipProvider {
}
/**
+ * Short-hand to load "about:blank". When "about:blank" is loaded AwContents will draw
+ * the background color specified by {@link AwContents#setBackgroundColor(int)}. This method
+ * guarantees that the next frame after invocation will draw the background
+ * color immediately without having to wait for the actual load to complete
+ * ({@link AwContentsClient#onPageFinished(String)}) or similar events.
+ */
+ public void loadBlank() {
+ loadUrl(new LoadUrlParams(BLANK_URL));
+ }
+
+ /**
* Load url without fixing up the url string. Consumers of ContentView are responsible for
* ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
* off during user input).
@@ -1151,6 +1185,10 @@ public class AwContents implements SmartClipProvider {
public void loadUrl(LoadUrlParams params) {
if (isDestroyed()) return;
+ if (BLANK_URL.equals(params.getUrl())) {
+ mIsLoadingBlank = true;
+ }
+
if (params.getLoadUrlType() == LoadUrlParams.LOAD_TYPE_DATA
&& !params.isBaseUrlDataScheme()) {
// This allows data URLs with a non-data base URL access to file:///android_asset/ and
@@ -1243,7 +1281,9 @@ public class AwContents implements SmartClipProvider {
// Do not ask the ContentViewCore for the background color, as it will always
// report white prior to initial navigation or post destruction, whereas we want
// to use the client supplied base value in those cases.
- if (isDestroyed() || !mContentsClient.isCachedRendererBackgroundColorValid()) {
+ // When loading BLANK_URL we want to draw the client supplied base color immediately.
+ if (isDestroyed() || !mContentsClient.isCachedRendererBackgroundColorValid()
+ || mIsLoadingBlank) {
return mBaseBackgroundColor;
}
return mContentsClient.getCachedRendererBackgroundColor();
@@ -2020,6 +2060,31 @@ public class AwContents implements SmartClipProvider {
if (!isDestroyed()) nativeSetJsOnlineProperty(mNativeAwContents, networkUp);
}
+ /**
+ * Callback used when flushing the visual state, see {@link #flushVisualState}.
+ */
+ @VisibleForTesting
+ public abstract static class VisualStateFlushCallback {
+ public abstract void onComplete();
+ public abstract void onFailure(int reason);
+ }
+
+ /**
+ * Flush the visual state.
+ *
+ * Flushing the visual state means queuing a callback in Blink that will be invoked when the
+ * contents of the DOM tree at the moment that the callback was enqueued (or later) are drawn
+ * into the screen. In other words, the following events need to happen before the callback is
+ * invoked:
+ * 1. The DOM tree is committed becoming the pending tree - see ThreadProxy::BeginMainFrame
+ * 2. The pending tree is activated becoming the active tree
+ * 3. A frame swap happens that draws the active tree into the screen
+ */
+ @VisibleForTesting
+ public void flushVisualState(VisualStateFlushCallback callback) {
+ nativeFlushVisualState(mNativeAwContents, callback);
+ }
+
//--------------------------------------------------------------------------------------------
// Methods called from native via JNI
//--------------------------------------------------------------------------------------------
@@ -2123,6 +2188,15 @@ public class AwContents implements SmartClipProvider {
mContentsClient.getCallbackHelper().postOnNewPicture(mPictureListenerContentProvider);
}
+ @CalledByNative
+ public static void flushVisualStateCallback(VisualStateFlushCallback callback, int value) {
+ if (value == 0) {
+ callback.onComplete();
+ } else {
+ callback.onFailure(value);
+ }
+ }
+
// Called as a result of nativeUpdateLastHitTestData.
@CalledByNative
private void updateHitTestData(
@@ -2337,8 +2411,9 @@ public class AwContents implements SmartClipProvider {
@Override
public void onDraw(Canvas canvas) {
- if (isDestroyed()) {
- TraceEvent.instant("EarlyOut_destroyed");
+ if (isDestroyed() || mIsLoadingBlank) {
+ String trace = isDestroyed() ? "EarlyOut_destroyed" : "EarlyOut_loadingBlank";
+ TraceEvent.instant(trace);
canvas.drawColor(getEffectiveBackgroundColor());
return;
}
@@ -2688,6 +2763,8 @@ public class AwContents implements SmartClipProvider {
private native long nativeGetAwDrawGLViewContext(long nativeAwContents);
private native long nativeCapturePicture(long nativeAwContents, int width, int height);
private native void nativeEnableOnNewPicture(long nativeAwContents, boolean enabled);
+ private native void nativeFlushVisualState(long nativeAwContents,
+ VisualStateFlushCallback callback);
private native void nativeClearView(long nativeAwContents);
private native void nativeSetExtraHeadersForUrl(long nativeAwContents,
String url, String extraHeaders);

Powered by Google App Engine
This is Rietveld 408576698