From 7a02d6e457073bd7f00546ff4b5b442937724651 Mon Sep 17 00:00:00 2001 From: Grace Kloba Date: Tue, 18 Aug 2009 10:10:51 -0700 Subject: [PATCH] Couple of fixes for viewport. http://b/issue?id=2053685. This is a tricky one. When Browser is restarted, we may get first layout even before viewport tag is parsed. This is rare, but it happens to Google Reader site. So we need to setup the viewport explicitly if it happens after first layout. There is a pairing webkit change. http://b/issue?id=2054131. When Google talk is loaded, it goes through an auth redirect site which means first layout is called with standardLoad as false. In this case, even the final site uses viewport tag to get mobile experience, the intermediate one doesn't. To make sure most of the mobile sites, who define their viewport width as device width, work correctly, we always update the mRestoreState when we set viewport. http://b/issue?id=2054121. When Browser is first started or restarted, the mCurrentViewWidth is 0 as we don't know the WebView's width yet. As we can't send VIEW_SIZE_CHANGED message directly, we reset WebView's mLastWidthSent so that VIEW_SIZE_CHANGED will be sent from WebView when it's width is available. --- core/java/android/webkit/WebViewCore.java | 66 +++++++++++++++-------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 0720beb9cee83..dee62b41463ab 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1778,12 +1778,27 @@ final class WebViewCore { mBrowserFrame.didFirstLayout(); - // reset the scroll position as it is a new page now - mWebkitScrollX = mWebkitScrollY = 0; + if (mWebView == null) return; - // for non-standard load, we only adjust scale if mRestoredScale > 0 - if (mWebView == null || (mRestoredScale == 0 && !standardLoad)) return; + setupViewport(standardLoad || mRestoredScale > 0); + // reset the scroll position, the restored offset and scales + mWebkitScrollX = mWebkitScrollY = mRestoredX = mRestoredY + = mRestoredScale = mRestoredScreenWidthScale = 0; + } + + // called by JNI + private void updateViewport() { + // if updateViewport is called before first layout, wait until first + // layout to update the viewport. In the rare case, this is called after + // first layout, force an update as we have just parsed the viewport + // meta tag. + if (mBrowserFrame.firstLayoutDone()) { + setupViewport(true); + } + } + + private void setupViewport(boolean updateRestoreState) { // set the viewport settings from WebKit setViewportSettingsFromNative(); @@ -1834,6 +1849,9 @@ final class WebViewCore { mViewportWidth = 0; } + // if mViewportWidth is 0, it means device-width, always update. + if (mViewportWidth != 0 && !updateRestoreState) return; + // now notify webview int webViewWidth = Math.round(mCurrentViewWidth * mCurrentViewScale); mRestoreState = new RestoreState(); @@ -1884,25 +1902,29 @@ final class WebViewCore { data.mScale = -1.0f; mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, EventHub.VIEW_SIZE_CHANGED, data)); - } else if (mSettings.getUseWideViewPort() && mCurrentViewWidth > 0) { - WebView.ViewSizeData data = new WebView.ViewSizeData(); - // mViewScale as 0 means it is in zoom overview mode. So we don't - // know the exact scale. If mRestoredScale is non-zero, use it; - // otherwise just use mTextWrapScale as the initial scale. - data.mScale = mRestoreState.mViewScale == 0 - ? (mRestoredScale > 0 ? mRestoredScale - : mRestoreState.mTextWrapScale) - : mRestoreState.mViewScale; - data.mWidth = Math.round(webViewWidth / data.mScale); - data.mHeight = mCurrentViewHeight * data.mWidth - / mCurrentViewWidth; - data.mTextWrapWidth = Math.round(webViewWidth - / mRestoreState.mTextWrapScale); - mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, - EventHub.VIEW_SIZE_CHANGED, data)); + } else if (mSettings.getUseWideViewPort()) { + if (mCurrentViewWidth == 0) { + // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView + // to WebViewCore + mWebView.mLastWidthSent = 0; + } else { + WebView.ViewSizeData data = new WebView.ViewSizeData(); + // mViewScale as 0 means it is in zoom overview mode. So we don't + // know the exact scale. If mRestoredScale is non-zero, use it; + // otherwise just use mTextWrapScale as the initial scale. + data.mScale = mRestoreState.mViewScale == 0 + ? (mRestoredScale > 0 ? mRestoredScale + : mRestoreState.mTextWrapScale) + : mRestoreState.mViewScale; + data.mWidth = Math.round(webViewWidth / data.mScale); + data.mHeight = mCurrentViewHeight * data.mWidth + / mCurrentViewWidth; + data.mTextWrapWidth = Math.round(webViewWidth + / mRestoreState.mTextWrapScale); + mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, + EventHub.VIEW_SIZE_CHANGED, data)); + } } - // reset restored offset, scale - mRestoredX = mRestoredY = mRestoredScale = mRestoredScreenWidthScale = 0; } // called by JNI