Couple of tuning for the Browser zoom.

1. Added a setting to control whether a page is loaded with overview mode;
2. If there is no viewport metag tag, a page will be loaded in the viewport
   at least 800px wide.
3. When we adjust zoom scale in the overview mode, don't use animation.
4. When zoom out to close to min zoom scale, switch to overview mode. So double
   tap will always have visual feedback unless it is mobile site.
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index e5813e6..eeac1d2 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -185,6 +185,7 @@
     private boolean         mSupportZoom = true;
     private boolean         mBuiltInZoomControls = false;
     private boolean         mAllowFileAccess = true;
+    private boolean         mLoadWithOverviewMode = true;
 
     // Class to handle messages before WebCore is ready.
     private class EventHandler {
@@ -427,6 +428,22 @@
     }
 
     /**
+     * Set whether the WebView loads a page with overview mode.
+     * @hide Pending API council approval
+     */
+    public void setLoadWithOverviewMode(boolean overview) {
+        mLoadWithOverviewMode = overview;
+    }
+
+    /**
+     * Returns true if this WebView loads page with overview mode
+     * @hide Pending API council approval
+     */
+    public boolean getLoadWithOverviewMode() {
+        return mLoadWithOverviewMode;
+    }
+
+    /**
      * Store whether the WebView is saving form data.
      */
     public void setSaveFormData(boolean save) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 444ef54..2d87dd2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -508,16 +508,13 @@
         "REQUEST_KEYBOARD" //                = 27;
     };
 
-    // width which view is considered to be fully zoomed out
-    static final int ZOOM_OUT_WIDTH = 1008;
-
     // default scale limit. Depending on the display density
     private static float DEFAULT_MAX_ZOOM_SCALE;
     private static float DEFAULT_MIN_ZOOM_SCALE;
     // scale limit, which can be set through viewport meta tag in the web page
     private float mMaxZoomScale;
     private float mMinZoomScale;
-    private boolean mMinZoomScaleFixed = false;
+    private boolean mMinZoomScaleFixed = true;
 
     // initial scale in percent. 0 means using default.
     private int mInitialScale = 0;
@@ -529,7 +526,7 @@
     boolean mInZoomOverview = false;
     // ideally mZoomOverviewWidth should be mContentWidth. But sites like espn,
     // engadget always have wider mContentWidth no matter what viewport size is.
-    int mZoomOverviewWidth = 0;
+    int mZoomOverviewWidth = WebViewCore.DEFAULT_VIEWPORT_WIDTH;
     float mLastScale;
 
     // default scale. Depending on the display density.
@@ -3686,9 +3683,8 @@
         // update mMinZoomScale if the minimum zoom scale is not fixed
         if (!mMinZoomScaleFixed) {
             mMinZoomScale = (float) getViewWidth()
-                    / Math.max(ZOOM_OUT_WIDTH, mDrawHistory ? mHistoryPicture
-                            .getWidth() : (mZoomOverviewWidth > 0 ?
-                                    mZoomOverviewWidth : mContentWidth));
+                    / (mDrawHistory ? mHistoryPicture.getWidth()
+                            : mZoomOverviewWidth);
         }
 
         // we always force, in case our height changed, in which case we still
@@ -4564,10 +4560,18 @@
     public boolean zoomOut() {
         // TODO: alternatively we can disallow this during draw history mode
         switchOutDrawHistory();
-        // Center zooming to the center of the screen.
-        mZoomCenterX = getViewWidth() * .5f;
-        mZoomCenterY = getViewHeight() * .5f;
-        return zoomWithPreview(mActualScale * 0.8f);
+        float scale = mActualScale * 0.8f;
+        if (scale < (mMinZoomScale + 0.1f) && WebView.ENABLE_DOUBLETAP_ZOOM
+                && mWebViewCore.getSettings().getUseWideViewPort()) {
+            // when zoom out to min scale, switch to overview mode
+            doDoubleTap();
+            return true;
+        } else {
+            // Center zooming to the center of the screen.
+            mZoomCenterX = getViewWidth() * .5f;
+            mZoomCenterY = getViewHeight() * .5f;
+            return zoomWithPreview(scale);
+        }
     }
 
     private void updateSelection() {
@@ -4666,14 +4670,6 @@
         mZoomCenterY = mLastTouchY;
         mInZoomOverview = !mInZoomOverview;
         if (mInZoomOverview) {
-            float newScale = (float) getViewWidth()
-                    / (mZoomOverviewWidth > 0 ? mZoomOverviewWidth
-                            : mContentWidth);
-            if (Math.abs(newScale - mActualScale) < 0.01) {
-                mInZoomOverview = !mInZoomOverview;
-                // as it is already full screen, do nothing.
-                return;
-            }
             if (getSettings().getBuiltInZoomControls()) {
                 if (mZoomButtonsController.isVisible()) {
                     mZoomButtonsController.setVisible(false);
@@ -4686,7 +4682,7 @@
                     mZoomControls.hide();
                 }
             }
-            zoomWithPreview(newScale);
+            zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
         } else {
             // mLastTouchX and mLastTouchY are the point in the current viewport
             int contentX = viewToContent((int) mLastTouchX + mScrollX);
@@ -4992,14 +4988,14 @@
                 case SPAWN_SCROLL_TO_MSG_ID:
                     spawnContentScrollTo(msg.arg1, msg.arg2);
                     break;
-                case NEW_PICTURE_MSG_ID:
+                case NEW_PICTURE_MSG_ID: {
+                    WebSettings settings = mWebViewCore.getSettings();
                     // called for new content
                     final int viewWidth = getViewWidth();
                     final WebViewCore.DrawData draw =
                             (WebViewCore.DrawData) msg.obj;
                     final Point viewSize = draw.mViewPoint;
-                    boolean useWideViewport =
-                            mWebViewCore.getSettings().getUseWideViewPort();
+                    boolean useWideViewport = settings.getUseWideViewPort();
                     WebViewCore.RestoreState restoreState = draw.mRestoreState;
                     if (restoreState != null) {
                         mInZoomOverview = false;
@@ -5017,7 +5013,8 @@
                             mMaxZoomScale = restoreState.mMaxScale;
                         }
                         if (useWideViewport && restoreState.mViewScale == 0) {
-                            mInZoomOverview = ENABLE_DOUBLETAP_ZOOM;
+                            mInZoomOverview = ENABLE_DOUBLETAP_ZOOM
+                                    && settings.getLoadWithOverviewMode();
                         }
                         setNewZoomScale(mLastScale, false);
                         setContentScrollTo(restoreState.mScrollX,
@@ -5050,21 +5047,19 @@
                                 draw.mViewPoint.x);
                     }
                     if (!mMinZoomScaleFixed) {
-                        mMinZoomScale = (float) viewWidth
-                                / Math.max(ZOOM_OUT_WIDTH,
-                                mZoomOverviewWidth > 0 ? mZoomOverviewWidth
-                                        : mContentWidth);
+                        mMinZoomScale = (float) viewWidth / mZoomOverviewWidth;
                     }
                     if (!mDrawHistory && mInZoomOverview) {
                         // fit the content width to the current view. Ignore
                         // the rounding error case.
                         if (Math.abs((viewWidth * mInvActualScale)
                                 - mZoomOverviewWidth) > 1) {
-                            zoomWithPreview((float) viewWidth
-                                    / mZoomOverviewWidth);
+                            setNewZoomScale((float) viewWidth
+                                    / mZoomOverviewWidth, false);
                         }
                     }
                     break;
+                }
                 case WEBCORE_INITIALIZED_MSG_ID:
                     // nativeCreate sets mNativeClass to a non-zero value
                     nativeCreate(msg.arg1);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ff4e736..86b0843 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -105,6 +105,10 @@
     private int mWebkitScrollX = 0;
     private int mWebkitScrollY = 0;
 
+    // If the site doesn't use viewport meta tag to specify the viewport, use
+    // DEFAULT_VIEWPORT_WIDTH as default viewport width
+    static final int DEFAULT_VIEWPORT_WIDTH = 800;
+
     // The thread name used to identify the WebCore thread and for use in
     // debugging other classes that require operation within the WebCore thread.
     /* package */ static final String THREAD_NAME = "WebViewCoreThread";
@@ -1419,7 +1423,7 @@
             if (mViewportWidth == -1) {
                 if (mSettings.getLayoutAlgorithm() ==
                         WebSettings.LayoutAlgorithm.NORMAL) {
-                    width = WebView.ZOOM_OUT_WIDTH;
+                    width = DEFAULT_VIEWPORT_WIDTH;
                 } else {
                     /*
                      * if a page's minimum preferred width is wider than the
@@ -1433,7 +1437,8 @@
                      * In the worse case, the native width will be adjusted when
                      * next zoom or screen orientation change happens.
                      */
-                    width = Math.max(w, nativeGetContentMinPrefWidth());
+                    width = Math.max(w, Math.max(DEFAULT_VIEWPORT_WIDTH,
+                            nativeGetContentMinPrefWidth()));
                 }
             } else {
                 width = Math.max(w, mViewportWidth);
@@ -1530,7 +1535,8 @@
             // layout.
             draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight);
             if (WebView.ENABLE_DOUBLETAP_ZOOM && mSettings.getUseWideViewPort()) {
-                draw.mMinPrefWidth = nativeGetContentMinPrefWidth();
+                draw.mMinPrefWidth = Math.max(DEFAULT_VIEWPORT_WIDTH,
+                        nativeGetContentMinPrefWidth());
             }
             if (mRestoreState != null) {
                 draw.mRestoreState = mRestoreState;