Providing plugins with scrolling ability as well as an event informing the plugin of the document's visibleRect.
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 8b8d315..73430ce 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -294,6 +294,11 @@
     m_check_domtree_version = true;
     m_progressDone = false;
     m_hasCursorBounds = false;
+
+    m_scrollOffsetX = 0;
+    m_scrollOffsetY = 0;
+    m_screenWidth = 0;
+    m_screenHeight = 0;
 }
 
 static bool layoutIfNeededRecursive(WebCore::Frame* f)
@@ -874,6 +879,9 @@
         m_mainFrame->view()->platformWidget()->setLocation(m_scrollOffsetX,
                 m_scrollOffsetY);
         m_mainFrame->eventHandler()->sendScrollEvent();
+
+        // update the currently visible window
+        sendVisibleRectBounds();
     }
     gCursorBoundsMutex.lock();
     bool hasCursorBounds = m_hasCursorBounds;
@@ -902,6 +910,7 @@
     DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%d) new:(w=%d,h=%d,sw=%d,scale=%d)",
         ow, oh, osw, m_scale, width, height, screenWidth, scale);
     m_screenWidth = screenWidth;
+    m_screenHeight = screenHeight;
     m_scale = scale;
     m_maxXScroll = screenWidth >> 2;
     m_maxYScroll = (screenWidth * height / width) >> 2;
@@ -946,6 +955,20 @@
                 false);
         }
     }
+
+    // update the currently visible window
+    sendVisibleRectBounds();
+}
+
+void WebViewCore::sendVisibleRectBounds()
+{
+    ANPEvent event;
+    SkANP::InitEvent(&event, kVisibleRect_ANPEventType);
+    event.data.visibleRect.x = m_scrollOffsetX;
+    event.data.visibleRect.y = m_scrollOffsetY;
+    event.data.visibleRect.width = m_screenWidth;
+    event.data.visibleRect.height = m_screenHeight;
+    sendPluginEvent(event, kVisibleRect_ANPEventFlag);
 }
 
 void WebViewCore::dumpDomTree(bool useFile)
@@ -1109,6 +1132,16 @@
     }
 }
 
+void WebViewCore::sendPluginEvent(const ANPEvent& evt, ANPEventFlag flag)
+{
+    PluginWidgetAndroid** iter = m_plugins.begin();
+    PluginWidgetAndroid** stop = m_plugins.end();
+    for (; iter < stop; ++iter) {
+        if((*iter)->isAcceptingEvent(flag))
+            (*iter)->sendEvent(evt);
+    }
+}
+
 void WebViewCore::sendPluginEvent(const ANPEvent& evt)
 {
     PluginWidgetAndroid** iter = m_plugins.begin();
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 4ba0074..4e737b6 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -26,6 +26,7 @@
 #ifndef WEBVIEWCORE_H
 #define WEBVIEWCORE_H
 
+#include "android_npapi.h"
 #include "CacheBuilder.h"
 #include "CachedHistory.h"
 #include "PictureSet.h"
@@ -55,7 +56,6 @@
 struct PluginWidgetAndroid;
 class SkPicture;
 class SkIRect;
-struct ANPEvent;
 
 namespace android {
 
@@ -291,6 +291,9 @@
         // send this event to all of the plugins in our list
         void sendPluginEvent(const ANPEvent&);
 
+        // send this event to all of the plugins who have the given flag set
+        void sendPluginEvent(const ANPEvent& evt, ANPEventFlag flag);
+
         // Notify the Java side whether it needs to pass down the touch events
         void needTouchEvents(bool);
 
@@ -384,7 +387,8 @@
         int m_lastVelocity;
         CachedHistory m_history;
         WebCore::Node* m_snapAnchorNode;
-        int m_screenWidth;
+        int m_screenWidth; // width of the visible rect in document coordinates
+        int m_screenHeight;// height of the visible rect in document coordinates
         int m_scale;
         unsigned m_domtree_version;
         bool m_check_domtree_version;
@@ -399,6 +403,7 @@
         SkPicture* rebuildPicture(const SkIRect& inval);
         void rebuildPictureSet(PictureSet* );
         void sendNotifyProgressFinished();
+        void sendVisibleRectBounds();
         bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
 #if DEBUG_NAV_UI
         uint32_t m_now;
diff --git a/WebKit/android/plugins/ANPWindowInterface.cpp b/WebKit/android/plugins/ANPWindowInterface.cpp
index 4aa862b..8258936 100644
--- a/WebKit/android/plugins/ANPWindowInterface.cpp
+++ b/WebKit/android/plugins/ANPWindowInterface.cpp
@@ -26,6 +26,9 @@
 // must include config.h first for webkit to fiddle with new/delete
 #include "config.h"
 #include "SkANP.h"
+#include "ScrollView.h"
+#include "WebViewCore.h"
+#include "PluginView.h"
 
 static bool anp_lockRect(void* window, const ANPRectI* inval,
                          ANPBitmap* bitmap) {
@@ -48,15 +51,28 @@
 static void anp_unlock(void* window) {
 }
 
+static PluginView* pluginViewForInstance(NPP instance) {
+    if (instance && instance->ndata)
+        return static_cast<PluginView*>(instance->ndata);
+    return PluginView::currentPluginView();
+}
+
+static void anp_scrollTo(NPP instance, int32_t x, int32_t y) {
+    ScrollView* scrollView = pluginViewForInstance(instance)->parent();
+    android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
+    core->scrollTo(x,y,true);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #define ASSIGN(obj, name)   (obj)->name = anp_##name
 
 void ANPWindowInterfaceV0_Init(ANPInterface* value) {
     ANPWindowInterfaceV0* i = reinterpret_cast<ANPWindowInterfaceV0*>(value);
-    
+
     ASSIGN(i, lockRect);
     ASSIGN(i, lockRegion);
+    ASSIGN(i, scrollTo);
     ASSIGN(i, unlock);
 }
 
diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h
index 32fa1c0..7b703c0 100644
--- a/WebKit/android/plugins/android_npapi.h
+++ b/WebKit/android/plugins/android_npapi.h
@@ -160,8 +160,9 @@
     and touch events will be provided to the plugin.
  */
 enum ANPEventFlag {
-    kKey_ANPEventFlag      = 0x01,
-    kTouch_ANPEventFlag    = 0x02,
+    kKey_ANPEventFlag           = 0x01,
+    kTouch_ANPEventFlag         = 0x02,
+    kVisibleRect_ANPEventFlag   = 0x04,
 };
 typedef uint32_t ANPEventFlags;
 
@@ -608,6 +609,11 @@
         results. If lock returned false, unlock should not be called.
      */
     void    (*unlock)(void* window);
+    /** Given (x,y) coordinates in the document space the currently visible
+        window will be shifted so that window's upper left corner will be as
+        closely aligned to the coordinates as possible.
+     */
+    void    (*scrollTo)(NPP instance, int32_t x, int32_t y);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -692,11 +698,12 @@
 // HandleEvent
 
 enum ANPEventTypes {
-    kNull_ANPEventType      = 0,
-    kKey_ANPEventType       = 1,
-    kTouch_ANPEventType     = 2,
-    kDraw_ANPEventType      = 3,
-    kLifecycle_ANPEventType = 4
+    kNull_ANPEventType          = 0,
+    kKey_ANPEventType           = 1,
+    kTouch_ANPEventType         = 2,
+    kDraw_ANPEventType          = 3,
+    kLifecycle_ANPEventType     = 4,
+    kVisibleRect_ANPEventType   = 5,
 };
 typedef int32_t ANPEventType;
 
@@ -765,6 +772,12 @@
                 ANPBitmap   bitmap;
             } data;
         } draw;
+        struct {
+            int32_t         x;      // relative to the document
+            int32_t         y;      // relative to the document
+            int32_t         width;
+            int32_t         height;
+        } visibleRect;
         int32_t         other[8];
     } data;
 };