Chromium Code Reviews| 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..7fee065f83a1a62786342e0de1b05ddd04647703 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 from loadBlankImmediately. |
| + private boolean mIsLoadingBlankImmediately = 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 (mIsLoadingBlankImmediately && BLANK_URL.equals(url)) { |
|
mkosiba (inactive)
2015/01/14 18:17:12
this seems race-prone as we might end up running t
Ignacio Solla
2015/01/16 16:02:07
I doubt that the race that you describe will actua
mkosiba (inactive)
2015/01/19 11:15:57
yeath, sorry. I just wanted to say "at first glanc
Ignacio Solla
2015/01/19 18:26:40
Acknowledged.
|
| + // Waiting for onPageFinished before flashing ensures that the flush callback will not |
| + // be received before BLANK_URL has made it into the screen. |
| + flushVisualState(new VisualStateFlushCallback() { |
| + @Override |
| + public void onFailure(int reason) { |
| + mIsLoadingBlankImmediately = false; |
| + } |
| + |
| + @Override |
| + public void onComplete() { |
| + mIsLoadingBlankImmediately = false; |
| + } |
| + }); |
| + } |
| + } |
| + |
| public void clearView() { |
| if (!isDestroyed()) nativeClearView(mNativeAwContents); |
| } |
| @@ -1142,6 +1165,19 @@ public class AwContents implements SmartClipProvider { |
| } |
| /** |
| + * Loads "about:blank" and draws the background color specified by |
| + * {@link AwContents#setBackgroundColor(int)} immediately without having to wait for the |
| + * asynchronous load to complete ({@link AwContentsClient#onPageFinished(String)}). |
| + * |
| + * <p>This API is useful when recycling container views and want to clear the contents from the |
| + * old page immediately. |
| + */ |
| + public void loadBlankImmediately() { |
|
mkosiba (inactive)
2015/01/14 18:17:12
maybe ignore any extra calls for as long as mIsLoa
Ignacio Solla
2015/01/16 16:02:07
Done.
|
| + loadUrl(new LoadUrlParams(BLANK_URL)); |
| + mIsLoadingBlankImmediately = true; |
| + } |
| + |
| + /** |
| * 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). |
| @@ -1243,7 +1279,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() |
| + || mIsLoadingBlankImmediately) { |
| return mBaseBackgroundColor; |
| } |
| return mContentsClient.getCachedRendererBackgroundColor(); |
| @@ -2020,6 +2058,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 { |
|
mkosiba (inactive)
2015/01/14 18:17:12
these usually go at the top of the file
Ignacio Solla
2015/01/16 16:02:07
Done.
|
| + 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 +2186,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 +2409,9 @@ public class AwContents implements SmartClipProvider { |
| @Override |
| public void onDraw(Canvas canvas) { |
| - if (isDestroyed()) { |
| - TraceEvent.instant("EarlyOut_destroyed"); |
| + if (isDestroyed() || mIsLoadingBlankImmediately) { |
| + String trace = isDestroyed() ? "EarlyOut_destroyed" : "EarlyOut_loadingBlank"; |
| + TraceEvent.instant(trace); |
| canvas.drawColor(getEffectiveBackgroundColor()); |
| return; |
| } |
| @@ -2688,6 +2761,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); |