| 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);
|
|
|