add event interface for plugins, so they can post an event to themselves (from any thread)
diff --git a/WebKit/Android.mk b/WebKit/Android.mk
index 2f0b5d4..814c503 100644
--- a/WebKit/Android.mk
+++ b/WebKit/Android.mk
@@ -65,6 +65,7 @@
 	\
 	android/plugins/ANPBitmapInterface.cpp \
 	android/plugins/ANPCanvasInterface.cpp \
+	android/plugins/ANPEventInterface.cpp \
 	android/plugins/ANPLogInterface.cpp \
 	android/plugins/ANPMatrixInterface.cpp \
 	android/plugins/ANPPaintInterface.cpp \
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 0b7e63b..c6034aa 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -88,6 +88,7 @@
 #include "Settings.h"
 #include "SkANP.h"
 #include "SkTemplates.h"
+#include "SkTDArray.h"
 #include "SkTypes.h"
 #include "SkCanvas.h"
 #include "SkPicture.h"
@@ -139,6 +140,24 @@
 
 namespace android {
 
+static SkTDArray<WebViewCore*> gInstanceList;
+
+void WebViewCore::addInstance(WebViewCore* inst) {
+    *gInstanceList.append() = inst;
+}
+
+void WebViewCore::removeInstance(WebViewCore* inst) {
+    int index = gInstanceList.find(inst);
+    LOG_ASSERT(index >= 0, "RemoveInstance inst not found");
+    if (index >= 0) {
+        gInstanceList.removeShuffle(index);
+    }
+}
+
+bool WebViewCore::isInstance(WebViewCore* inst) {
+    return gInstanceList.find(inst) >= 0;
+}
+
 // ----------------------------------------------------------------------------
 
 #define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.m_nativeClass))
@@ -286,10 +305,14 @@
     PageGroup::setShouldTrackVisitedLinks(true);
 
     reset(true);
+
+    WebViewCore::addInstance(this);
 }
 
 WebViewCore::~WebViewCore()
 {
+    WebViewCore::removeInstance(this);
+
     // Release the focused view
     Release(m_popupReply);
 
@@ -1316,6 +1339,11 @@
     }
 }
 
+bool WebViewCore::isPlugin(PluginWidgetAndroid* w) const
+{
+    return m_plugins.find(w) >= 0;
+}
+
 void WebViewCore::invalPlugin(PluginWidgetAndroid* w)
 {
     const double PLUGIN_INVAL_DELAY = 1.0 / 60;
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index d1c8511..a469329 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -347,6 +347,8 @@
          */
         void addPlugin(PluginWidgetAndroid*);
         void removePlugin(PluginWidgetAndroid*);
+        // returns true if the pluginwidgit is in our active list
+        bool isPlugin(PluginWidgetAndroid*) const;
         void invalPlugin(PluginWidgetAndroid*);
         void drawPlugins();
 
@@ -513,6 +515,16 @@
 #if DEBUG_NAV_UI
         uint32_t m_now;
 #endif
+
+    private:
+        // called from constructor, to add this to a global list
+        static void addInstance(WebViewCore*);
+        // called from destructor, to remove this from a global list
+        static void removeInstance(WebViewCore*);
+    public:
+        // call only from webkit thread (like add/remove), return true if inst
+        // is still alive
+        static bool isInstance(WebViewCore*);
     };
 
 }   // namespace android
diff --git a/WebKit/android/plugins/ANPEventInterface.cpp b/WebKit/android/plugins/ANPEventInterface.cpp
new file mode 100644
index 0000000..2fdf159
--- /dev/null
+++ b/WebKit/android/plugins/ANPEventInterface.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// must include config.h first for webkit to fiddle with new/delete
+#include "config.h"
+#include "SkANP.h"
+#include "WebViewCore.h"
+#include "PluginView.h"
+#include "PluginWidgetAndroid.h"
+
+#include "JavaSharedClient.h"
+
+using namespace android;
+
+struct WrappedANPEvent {
+    WebViewCore*            fWVC;
+    PluginWidgetAndroid*    fPWA;
+    ANPEvent                fEvent;
+};
+
+/*  Its possible we may be called after the plugin that initiated the event
+    has been torn-down. Thus we check that the assicated webviewcore and
+    pluginwidget are still active before dispatching the event.
+ */
+static void send_anpevent(void* data) {
+    WrappedANPEvent* wrapper = static_cast<WrappedANPEvent*>(data);
+    WebViewCore* core = wrapper->fWVC;
+    PluginWidgetAndroid* widget = wrapper->fPWA;
+
+    // be sure we're still alive before delivering the event
+    if (WebViewCore::isInstance(core) && core->isPlugin(widget)) {
+        widget->sendEvent(wrapper->fEvent);
+    }
+    delete wrapper;
+}
+
+static void anp_postEvent(NPP instance, const ANPEvent* event) {
+    if (instance && instance->ndata && event) {
+        PluginView* pluginView = static_cast<PluginView*>(instance->ndata);
+        PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
+        WebViewCore* wvc = pluginWidget->webViewCore();
+
+        WrappedANPEvent* wrapper = new WrappedANPEvent;
+        // recored these, and recheck that they are valid before delivery
+        // in send_anpevent
+        wrapper->fWVC = pluginWidget->webViewCore();
+        wrapper->fPWA = pluginWidget;
+        // make a copy of the event
+        wrapper->fEvent = *event;
+        JavaSharedClient::EnqueueFunctionPtr(send_anpevent, wrapper);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define ASSIGN(obj, name)   (obj)->name = anp_##name
+
+void ANPEventInterfaceV0_Init(ANPInterface* value) {
+    ANPEventInterfaceV0* i = reinterpret_cast<ANPEventInterfaceV0*>(value);
+
+    ASSIGN(i, postEvent);
+}
diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h
index 14553ff..1111836 100644
--- a/WebKit/android/plugins/android_npapi.h
+++ b/WebKit/android/plugins/android_npapi.h
@@ -118,6 +118,7 @@
 #define kBitmapInterfaceV0_ANPGetValue      ((NPNVariable)1008)
 #define kSurfaceInterfaceV0_ANPGetValue     ((NPNVariable)1009)
 #define kSystemInterfaceV0_ANPGetValue      ((NPNVariable)1010)
+#define kEventInterfaceV0_ANPGetValue       ((NPNVariable)1011)
 
 /** queries for which drawing model is desired (for the draw event)
 
@@ -759,6 +760,21 @@
      */
     kDraw_ANPEventType          = 4,
     kLifecycle_ANPEventType     = 5,
+
+    /** This event type is completely defined by the plugin.
+        When creating an event, the caller must always set the first
+        two fields, the remaining data is optional.
+            ANPEvent evt;
+            evt.inSize = sizeof(ANPEvent);
+            evt.eventType = kCustom_ANPEventType
+            // other data slots are optional
+            evt.other[] = ...;
+        To post a copy of the event, call
+            eventInterface->postEvent(myNPPInstance, &evt);
+        That call makes a copy of the event struct, and post that on the event
+        queue for the plugin.
+     */
+    kCustom_ANPEventType   = 6,
 };
 typedef int32_t ANPEventType;
 
@@ -883,4 +899,14 @@
     } data;
 };
 
+struct ANPEventInterfaceV0 : ANPInterface {
+    /** Post a copy of the specified event to the plugin. The event will be
+        delivered to the plugin in its main thread (the thread that receives
+        other ANPEvents). If, after posting before delivery, the NPP instance
+        is torn down, the event will be discarded.
+     */
+    void (*postEvent)(NPP inst, const ANPEvent* event);
+};
+
+
 #endif