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.
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 0720beb..dee62b4 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1778,12 +1778,27 @@
 
         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 @@
             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 @@
             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