Merge "Call window.onscroll event at the end of scrolling."
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 88bb9fc..9ac91ac 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -636,13 +636,7 @@
     /*
      * Package message ids
      */
-    //! arg1=x, arg2=y
     static final int SCROLL_TO_MSG_ID                   = 101;
-    static final int SCROLL_BY_MSG_ID                   = 102;
-    //! arg1=x, arg2=y
-    static final int SPAWN_SCROLL_TO_MSG_ID             = 103;
-    //! arg1=x, arg2=y
-    static final int SYNC_SCROLL_TO_MSG_ID              = 104;
     static final int NEW_PICTURE_MSG_ID                 = 105;
     static final int UPDATE_TEXT_ENTRY_MSG_ID           = 106;
     static final int WEBCORE_INITIALIZED_MSG_ID         = 107;
@@ -698,9 +692,9 @@
 
     static final String[] HandlerPackageDebugString = {
         "SCROLL_TO_MSG_ID", //               = 101;
-        "SCROLL_BY_MSG_ID", //               = 102;
-        "SPAWN_SCROLL_TO_MSG_ID", //         = 103;
-        "SYNC_SCROLL_TO_MSG_ID", //          = 104;
+        "102", //                            = 102;
+        "103", //                            = 103;
+        "104", //                            = 104;
         "NEW_PICTURE_MSG_ID", //             = 105;
         "UPDATE_TEXT_ENTRY_MSG_ID", //       = 106;
         "WEBCORE_INITIALIZED_MSG_ID", //     = 107;
@@ -748,7 +742,9 @@
     // initial scale in percent. 0 means using default.
     private int mInitialScaleInPercent = 0;
 
-    private boolean mUserScroll = false;
+    // Whether or not a scroll event should be sent to webkit.  This is only set
+    // to false when restoring the scroll position.
+    private boolean mSendScrollEvent = true;
 
     private int mSnapScrollMode = SNAP_NONE;
     private static final int SNAP_NONE = 0;
@@ -2055,7 +2051,6 @@
         } else {
             y = -h / 2;
         }
-        mUserScroll = true;
         return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
                 : extendScroll(y);
     }
@@ -2081,7 +2076,6 @@
         } else {
             y = h / 2;
         }
-        mUserScroll = true;
         return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
                 : extendScroll(y);
     }
@@ -2515,7 +2509,7 @@
             Point pos = new Point(rect.left, rect.top);
             mWebViewCore.removeMessages(EventHub.SET_SCROLL_OFFSET);
             mWebViewCore.sendMessage(EventHub.SET_SCROLL_OFFSET,
-                    nativeMoveGeneration(), mUserScroll ? 1 : 0, pos);
+                    nativeMoveGeneration(), mSendScrollEvent ? 1 : 0, pos);
             mLastVisibleRectSent = rect;
             mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
         }
@@ -3183,6 +3177,9 @@
                 if (!mSelectingText) {
                     WebViewCore.resumeUpdatePicture(mWebViewCore);
                 }
+                if (oldX != mScrollX || oldY != mScrollY) {
+                    sendOurVisibleRect();
+                }
             }
         } else {
             super.computeScroll();
@@ -4161,9 +4158,6 @@
             mScrollX = pinLocX(mScrollX);
             mScrollY = pinLocY(mScrollY);
             if (oldScrollX != mScrollX || oldScrollY != mScrollY) {
-                mUserScroll = false;
-                mWebViewCore.sendMessage(EventHub.SYNC_SCROLL, oldScrollX,
-                        oldScrollY);
                 onScrollChanged(mScrollX, mScrollY, oldScrollX, oldScrollY);
             } else {
                 sendOurVisibleRect();
@@ -5704,7 +5698,6 @@
                         mHeldMotionless = MOTIONLESS_FALSE;
                     }
                     mLastTouchTime = eventTime;
-                    mUserScroll = true;
                 }
 
                 doDrag(deltaX, deltaY);
@@ -6405,7 +6398,6 @@
             if (xMove != 0 || yMove != 0) {
                 pinScrollBy(xMove, yMove, true, 0);
             }
-            mUserScroll = true;
         }
     }
 
@@ -7156,20 +7148,10 @@
                     doShortPress();
                     break;
                 }
-                case SCROLL_BY_MSG_ID:
-                    setContentScrollBy(msg.arg1, msg.arg2, (Boolean) msg.obj);
-                    break;
-                case SYNC_SCROLL_TO_MSG_ID:
-                    if (mUserScroll) {
-                        // if user has scrolled explicitly, don't sync the
-                        // scroll position any more
-                        mUserScroll = false;
-                        break;
-                    }
-                    setContentScrollTo(msg.arg1, msg.arg2);
-                    break;
-                case SCROLL_TO_MSG_ID:
-                    if (((Boolean) msg.obj).booleanValue()) {
+                case SCROLL_TO_MSG_ID: {
+                    // arg1 = animate, arg2 = onlyIfImeIsShowing
+                    // obj = Point(x, y)
+                    if (msg.arg2 == 1) {
                         // This scroll is intended to bring the textfield into
                         // view, but is only necessary if the IME is showing
                         InputMethodManager imm = InputMethodManager.peekInstance();
@@ -7179,18 +7161,14 @@
                             break;
                         }
                     }
-                    if (setContentScrollTo(msg.arg1, msg.arg2)) {
-                        // if we can't scroll to the exact position due to pin,
-                        // send a message to WebCore to re-scroll when we get a
-                        // new picture
-                        mUserScroll = false;
-                        mWebViewCore.sendMessage(EventHub.SYNC_SCROLL,
-                                msg.arg1, msg.arg2);
+                    final Point p = (Point) msg.obj;
+                    if (msg.arg1 == 1) {
+                        spawnContentScrollTo(p.x, p.y);
+                    } else {
+                        setContentScrollTo(p.x, p.y);
                     }
                     break;
-                case SPAWN_SCROLL_TO_MSG_ID:
-                    spawnContentScrollTo(msg.arg1, msg.arg2);
-                    break;
+                }
                 case UPDATE_ZOOM_RANGE: {
                     WebViewCore.ViewState viewState = (WebViewCore.ViewState) msg.obj;
                     // mScrollX contains the new minPrefWidth
@@ -7203,7 +7181,6 @@
                 }
                 case NEW_PICTURE_MSG_ID: {
                     // called for new content
-                    mUserScroll = false;
                     final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
                     setBaseLayer(draw.mBaseLayer, draw.mInvalRegion.getBounds());
                     final Point viewSize = draw.mViewSize;
@@ -7214,7 +7191,14 @@
                         mLastWidthSent = 0;
                         mZoomManager.onFirstLayout(draw);
                         if (!mDrawHistory) {
+                            // Do not send the scroll event for this particular
+                            // scroll message.  Note that a scroll event may
+                            // still be fired if the user scrolls before the
+                            // message can be handled.
+                            mSendScrollEvent = false;
                             setContentScrollTo(viewState.mScrollX, viewState.mScrollY);
+                            mSendScrollEvent = true;
+
                             // As we are on a new page, remove the WebTextView. This
                             // is necessary for page loads driven by webkit, and in
                             // particular when the user was on a password field, so
@@ -8140,7 +8124,6 @@
                     + contentCursorRingBounds);
         }
         requestRectangleOnScreen(viewCursorRingBounds);
-        mUserScroll = true;
         return keyHandled;
     }
 
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index a9102e9..42889cb 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -124,9 +124,6 @@
     private int mRestoredX = 0;
     private int mRestoredY = 0;
 
-    private int mWebkitScrollX = 0;
-    private int mWebkitScrollY = 0;
-
     private DeviceMotionAndOrientationManager mDeviceMotionAndOrientationManager =
             new DeviceMotionAndOrientationManager(this);
     private DeviceMotionService mDeviceMotionService;
@@ -868,7 +865,7 @@
             "SAVE_DOCUMENT_STATE", // = 128;
             "129", // = 129;
             "WEBKIT_DRAW", // = 130;
-            "SYNC_SCROLL", // = 131;
+            "131", // = 131;
             "POST_URL", // = 132;
             "SPLIT_PICTURE_SET", // = 133;
             "CLEAR_CONTENT", // = 134;
@@ -926,7 +923,6 @@
         static final int SAVE_DOCUMENT_STATE = 128;
 
         static final int WEBKIT_DRAW = 130;
-        static final int SYNC_SCROLL = 131;
         static final int POST_URL = 132;
         static final int SPLIT_PICTURE_SET = 133;
         static final int CLEAR_CONTENT = 134;
@@ -1184,7 +1180,8 @@
                             // note: these are in document coordinates
                             // (inv-zoom)
                             Point pt = (Point) msg.obj;
-                            nativeSetScrollOffset(msg.arg1, msg.arg2, pt.x, pt.y);
+                            nativeSetScrollOffset(msg.arg1, msg.arg2 == 1,
+                                    pt.x, pt.y);
                             break;
 
                         case SET_GLOBAL_BOUNDS:
@@ -1476,11 +1473,6 @@
                                     data.mAllow, data.mRemember);
                             break;
 
-                        case SYNC_SCROLL:
-                            mWebkitScrollX = msg.arg1;
-                            mWebkitScrollY = msg.arg2;
-                            break;
-
                         case SPLIT_PICTURE_SET:
                             nativeSplitContent(msg.arg1);
                             mWebView.mPrivateHandler.obtainMessage(
@@ -1496,9 +1488,7 @@
                             break;
 
                         case MESSAGE_RELAY:
-                            if (msg.obj instanceof Message) {
-                                ((Message) msg.obj).sendToTarget();
-                            }
+                            ((Message) msg.obj).sendToTarget();
                             break;
 
                         case POPULATE_VISITED_LINKS:
@@ -2002,13 +1992,6 @@
             if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
             Message.obtain(mWebView.mPrivateHandler,
                     WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
-            if (mWebkitScrollX != 0 || mWebkitScrollY != 0) {
-                // as we have the new picture, try to sync the scroll position
-                Message.obtain(mWebView.mPrivateHandler,
-                        WebView.SYNC_SCROLL_TO_MSG_ID, mWebkitScrollX,
-                        mWebkitScrollY).sendToTarget();
-                mWebkitScrollX = mWebkitScrollY = 0;
-            }
         }
     }
 
@@ -2111,25 +2094,8 @@
     }
 
     // called by JNI
-    private void contentScrollBy(int dx, int dy, boolean animate) {
-        if (!mBrowserFrame.firstLayoutDone()) {
-            // Will this happen? If yes, we need to do something here.
-            return;
-        }
-        if (mWebView != null) {
-            Message msg = Message.obtain(mWebView.mPrivateHandler,
-                    WebView.SCROLL_BY_MSG_ID, dx, dy, Boolean.valueOf(animate));
-            if (mDrawIsScheduled) {
-                mEventHub.sendMessage(Message.obtain(null,
-                        EventHub.MESSAGE_RELAY, msg));
-            } else {
-                msg.sendToTarget();
-            }
-        }
-    }
-
-    // called by JNI
-    private void contentScrollTo(int x, int y, boolean onlyIfImeIsShowing) {
+    private void contentScrollTo(int x, int y, boolean animate,
+            boolean onlyIfImeIsShowing) {
         if (!mBrowserFrame.firstLayoutDone()) {
             /*
              * WebKit restore state will be called before didFirstLayout(),
@@ -2142,32 +2108,8 @@
         }
         if (mWebView != null) {
             Message msg = Message.obtain(mWebView.mPrivateHandler,
-                    WebView.SCROLL_TO_MSG_ID, x, y,
-                    Boolean.valueOf(onlyIfImeIsShowing));
-            if (mDrawIsScheduled) {
-                mEventHub.sendMessage(Message.obtain(null,
-                        EventHub.MESSAGE_RELAY, msg));
-            } else {
-                msg.sendToTarget();
-            }
-        }
-    }
-
-    // called by JNI
-    private void contentSpawnScrollTo(int x, int y) {
-        if (!mBrowserFrame.firstLayoutDone()) {
-            /*
-             * WebKit restore state will be called before didFirstLayout(),
-             * remember the position as it has to be applied after restoring
-             * zoom factor which is controlled by screenWidth.
-             */
-            mRestoredX = x;
-            mRestoredY = y;
-            return;
-        }
-        if (mWebView != null) {
-            Message msg = Message.obtain(mWebView.mPrivateHandler,
-                    WebView.SPAWN_SCROLL_TO_MSG_ID, x, y);
+                    WebView.SCROLL_TO_MSG_ID, animate ? 1 : 0,
+                    onlyIfImeIsShowing ? 1 : 0, new Point(x, y));
             if (mDrawIsScheduled) {
                 mEventHub.sendMessage(Message.obtain(null,
                         EventHub.MESSAGE_RELAY, msg));
@@ -2244,7 +2186,7 @@
         }
 
         // reset the scroll position, the restored offset and scales
-        mWebkitScrollX = mWebkitScrollY = mRestoredX = mRestoredY = 0;
+        mRestoredX = mRestoredY = 0;
         mRestoredScale = mRestoredTextWrapScale = 0;
     }
 
@@ -2506,7 +2448,7 @@
     private native void nativeScrollFocusedTextInput(float xPercent, int y);
 
     // these must be in document space (i.e. not scaled/zoomed).
-    private native void nativeSetScrollOffset(int gen, int userScrolled, int dx, int dy);
+    private native void nativeSetScrollOffset(int gen, boolean sendScrollEvent, int dx, int dy);
 
     private native void nativeSetGlobalBounds(int x, int y, int w, int h);