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

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: Address review comments 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 4d80be73e6d07d234a2cfeef69823b3e5675638d..9b59dbe22adbc917aa72b6b6cd43b180d5897832 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -94,6 +94,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.
@@ -182,6 +184,15 @@ public class AwContents implements SmartClipProvider {
}
}
+ /**
+ * 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);
+ }
+
private long mNativeAwContents;
private final AwBrowserContext mBrowserContext;
private ViewGroup mContainerView;
@@ -256,6 +267,9 @@ public class AwContents implements SmartClipProvider {
// when in this state.
private boolean mTemporarilyDetached;
+ // This flag indicates that we're currently loading BLANK_URL from loadBlankNow.
+ private boolean mIsLoadingBlankNow = false;
+
// True when this AwContents has been destroyed.
// Do not use directly, call isDestroyed() instead.
private boolean mIsDestroyed = false;
@@ -552,6 +566,34 @@ public class AwContents implements SmartClipProvider {
}
/**
+ * Extension of {@link AwWebContentsObserver} that adds functionality that {@link AwContents}
+ * encapsulates.
+ */
+ private class AwContentsAwWebContentsObserver extends AwWebContentsObserver {
+ public AwContentsAwWebContentsObserver(
+ WebContents webContents, AwContentsClient awContentsClient) {
+ super(webContents, awContentsClient);
+ }
+
+ @Override
+ public void didNavigateMainFrame(String url, String baseUrl,
+ boolean isNavigationToDifferentPage, boolean isFragmentNavigation) {
+ super.didNavigateMainFrame(
+ url, baseUrl, isNavigationToDifferentPage, isFragmentNavigation);
+ // Waiting for didNavigateMainFrame before flashing ensures that the flush callback will
mkosiba (inactive) 2015/01/19 11:15:58 nit: before flushing?
Ignacio Solla 2015/01/19 18:26:41 Done.
+ // not be received before BLANK_URL has made it into the screen.
+ flushVisualStateIfLoadingBlankNow(url);
+ }
+
+ @Override
+ public void didFailLoad(boolean isProvisionalLoad, boolean isMainFrame, int errorCode,
+ String description, String failingUrl) {
+ super.didFailLoad(isProvisionalLoad, isMainFrame, errorCode, description, failingUrl);
+ flushVisualStateIfLoadingBlankNow(failingUrl);
+ }
+ }
+
+ /**
* @param browserContext the browsing context to associate this view contents with.
* @param containerView the view-hierarchy item this object will be bound to.
* @param context the context to use, usually containerView.getContext().
@@ -835,7 +877,7 @@ public class AwContents implements SmartClipProvider {
if (mWebContentsObserver != null) {
mWebContentsObserver.detachFromWebContents();
}
- mWebContentsObserver = new AwWebContentsObserver(mWebContents, mContentsClient);
+ mWebContentsObserver = new AwContentsAwWebContentsObserver(mWebContents, mContentsClient);
}
/**
@@ -978,6 +1020,11 @@ public class AwContents implements SmartClipProvider {
return mNavigationController;
}
+ @VisibleForTesting
+ public Context getContext() {
mkosiba (inactive) 2015/01/19 11:15:58 I don't think you need this, the base test class h
Ignacio Solla 2015/01/19 18:26:41 Done.
+ return mContext;
+ }
+
// Can be called from any thread.
public AwSettings getSettings() {
return mSettings;
@@ -1144,6 +1191,38 @@ 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 loadBlankNow() {
+ if (mIsLoadingBlankNow) {
+ return;
+ }
+ loadUrl(new LoadUrlParams(BLANK_URL));
+ mIsLoadingBlankNow = true;
+ }
+
+ private void flushVisualStateIfLoadingBlankNow(String url) {
+ if (mIsLoadingBlankNow && BLANK_URL.equals(url)) {
+ flushVisualState(new VisualStateFlushCallback() {
+ @Override
+ public void onFailure(int reason) {
+ mIsLoadingBlankNow = false;
mkosiba (inactive) 2015/01/19 11:15:58 I think Bo mentioned you need to postInvalidateOnA
Ignacio Solla 2015/01/19 18:26:41 I propagate this bit to BVR. I'll ask Bo if we sti
Ignacio Solla 2015/01/19 18:31:57 Bo confirmed offline that EnsureContinuousInvalida
+ }
+
+ @Override
+ public void onComplete() {
+ mIsLoadingBlankNow = false;
+ }
+ });
+ }
+ }
+
+ /**
* 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 +1322,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()
+ || mIsLoadingBlankNow) {
return mBaseBackgroundColor;
}
return mContentsClient.getCachedRendererBackgroundColor();
@@ -2020,6 +2101,22 @@ public class AwContents implements SmartClipProvider {
if (!isDestroyed()) nativeSetJsOnlineProperty(mNativeAwContents, networkUp);
}
+ /**
+ * 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 +2220,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 +2443,9 @@ public class AwContents implements SmartClipProvider {
@Override
public void onDraw(Canvas canvas) {
- if (isDestroyed()) {
- TraceEvent.instant("EarlyOut_destroyed");
+ if (isDestroyed() || mIsLoadingBlankNow) {
+ String trace = isDestroyed() ? "EarlyOut_destroyed" : "EarlyOut_loadingBlank";
+ TraceEvent.instant(trace);
canvas.drawColor(getEffectiveBackgroundColor());
return;
}
@@ -2688,6 +2795,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