consolidating to only use one surface per plugin. give plugin access to java context.

There is a companion commit in frameworks/base.
diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp
index 65d3385..e10641d 100644
--- a/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -483,7 +483,13 @@
 
         case kSupportedDrawingModel_ANPGetValue: {
             uint32_t* bits = reinterpret_cast<uint32_t*>(value);
-            *bits = (1 << kBitmap_ANPDrawingModel);
+            *bits = kBitmap_ANPDrawingModel & kSurface_ANPDrawingModel;
+            return NPERR_NO_ERROR;
+        }
+
+        case kJavaContext_ANPGetValue: {
+            jobject* retObject = static_cast<jobject*>(value);
+            *retObject = android::WebViewCore::getWebViewCore(parent())->getContext();
             return NPERR_NO_ERROR;
         }
 
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 85b00e6..5d2b8bb 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -218,13 +218,13 @@
     jmethodID   m_geolocationPermissionsHidePrompt;
     jmethodID   m_addMessageToConsole;
     jmethodID   m_getPluginClass;
-    jmethodID   m_createPluginJavaInstance;
     jmethodID   m_showFullScreenPlugin;
     jmethodID   m_hideFullScreenPlugin;
     jmethodID   m_updateFullScreenPlugin;
-    jmethodID   m_createSurface;
+    jmethodID   m_addSurface;
     jmethodID   m_updateSurface;
     jmethodID   m_destroySurface;
+    jmethodID   m_getContext;
     jmethodID   m_sendFindAgain;
     AutoJObject object(JNIEnv* env) {
         return getRealObject(env, m_obj);
@@ -302,13 +302,13 @@
     m_javaGlue->m_geolocationPermissionsHidePrompt = GetJMethod(env, clazz, "geolocationPermissionsHidePrompt", "()V");
     m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;)V");
     m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
-    m_javaGlue->m_createPluginJavaInstance = GetJMethod(env, clazz, "createPluginJavaInstance", "(Ljava/lang/String;I)Landroid/webkit/plugin/WebkitPlugin;");
-    m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/plugin/WebkitPlugin;IIIII)V");
+    m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;IIIII)V");
     m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V");
     m_javaGlue->m_updateFullScreenPlugin = GetJMethod(env, clazz, "updateFullScreenPlugin", "(IIII)V");
-    m_javaGlue->m_createSurface = GetJMethod(env, clazz, "createSurface", "(Landroid/webkit/plugin/WebkitPlugin;IIII)Landroid/webkit/ViewManager$ChildView;");
+    m_javaGlue->m_addSurface = GetJMethod(env, clazz, "addSurface", "(Landroid/view/View;IIII)Landroid/webkit/ViewManager$ChildView;");
     m_javaGlue->m_updateSurface = GetJMethod(env, clazz, "updateSurface", "(Landroid/webkit/ViewManager$ChildView;IIII)V");
     m_javaGlue->m_destroySurface = GetJMethod(env, clazz, "destroySurface", "(Landroid/webkit/ViewManager$ChildView;)V");
+    m_javaGlue->m_getContext = GetJMethod(env, clazz, "getContext", "()Landroid/content/Context;");
     m_javaGlue->m_sendFindAgain = GetJMethod(env, clazz, "sendFindAgain", "()V");
 
     env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -2592,10 +2592,6 @@
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return NULL;
 
     jstring libString = env->NewString(libName.characters(), libName.length());
     jstring classString = env->NewStringUTF(className);
@@ -2615,40 +2611,15 @@
     }
 }
 
-jobject WebViewCore::createPluginJavaInstance(const WebCore::String& libName, NPP npp)
-{
-    JNIEnv* env = JSC::Bindings::getJNIEnv();
-    AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return 0;
-
-    jstring libString = env->NewString(libName.characters(), libName.length());
-    jobject result = env->CallObjectMethod(obj.get(),
-                                           m_javaGlue->m_createPluginJavaInstance,
-                                           libString, (int) npp);
-
-    //cleanup unneeded local JNI references
-    env->DeleteLocalRef(libString);
-
-    checkException(env);
-    return result;
-}
-
-void WebViewCore::showFullScreenPlugin(jobject webkitPlugin, NPP npp, int x,
+void WebViewCore::showFullScreenPlugin(jobject childView, NPP npp, int x,
         int y, int width, int height)
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return;
 
     env->CallVoidMethod(obj.get(),
                         m_javaGlue->m_showFullScreenPlugin,
-                        webkitPlugin, (int)npp, x, y, width, height);
+                        childView, (int)npp, x, y, width, height);
     checkException(env);
 }
 
@@ -2656,10 +2627,6 @@
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return;
 
     env->CallVoidMethod(obj.get(), m_javaGlue->m_hideFullScreenPlugin);
     checkException(env);
@@ -2669,41 +2636,28 @@
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return;
 
     env->CallVoidMethod(obj.get(), m_javaGlue->m_updateFullScreenPlugin, x, y,
             width, height);
     checkException(env);
 }
 
-jobject WebViewCore::createSurface(jobject webkitPlugin, int x, int y, int width, int height)
+jobject WebViewCore::addSurface(jobject view, int x, int y, int width, int height)
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return 0;
 
     jobject result = env->CallObjectMethod(obj.get(),
-                                           m_javaGlue->m_createSurface,
-                                           webkitPlugin, x, y, width, height);
+                                           m_javaGlue->m_addSurface,
+                                           view, x, y, width, height);
     checkException(env);
     return result;
-
 }
 
 void WebViewCore::updateSurface(jobject childView, int x, int y, int width, int height)
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return;
 
     env->CallVoidMethod(obj.get(), m_javaGlue->m_updateSurface, childView, x,
                         y, width, height);
@@ -2714,15 +2668,21 @@
 {
     JNIEnv* env = JSC::Bindings::getJNIEnv();
     AutoJObject obj = m_javaGlue->object(env);
-    // if it is called during DESTROY is handled, the real object of WebViewCore
-    // can be gone. Check before using it.
-    if (!obj.get())
-        return;
 
     env->CallVoidMethod(obj.get(), m_javaGlue->m_destroySurface, childView);
     checkException(env);
 }
 
+jobject WebViewCore::getContext()
+{
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    AutoJObject obj = m_javaGlue->object(env);
+
+    jobject result = env->CallObjectMethod(obj.get(), m_javaGlue->m_getContext);
+    checkException(env);
+    return result;
+}
+
 bool WebViewCore::validNodeAndBounds(Frame* frame, Node* node,
     const IntRect& originalAbsoluteBounds)
 {
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 9c9c510..f1893ff 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -384,9 +384,6 @@
         // Generates a class loader that contains classes from the plugin's apk
         jclass getPluginClass(const WebCore::String& libName, const char* className);
 
-        // Creates a new instance of the plugin's java component
-        jobject createPluginJavaInstance(const WebCore::String& libName, NPP npp);
-
         // Creates a full screen surface for a plugin
         void showFullScreenPlugin(jobject webkitPlugin, NPP npp, int x, int y, int width, int height);
 
@@ -396,8 +393,8 @@
         // Update coordinates and dimensions for a full screen plugin
         void updateFullScreenPlugin(int x, int y, int width, int height);
 
-        // Creates a Surface (i.e. View) for a plugin
-        jobject createSurface(jobject webkitPlugin, int x, int y, int width, int height);
+        // Adds the plugin's view (aka surface) to the view hierarchy
+        jobject addSurface(jobject view, int x, int y, int width, int height);
 
         // Updates a Surface coordinates and dimensions for a plugin
         void updateSurface(jobject childView, int x, int y, int width, int height);
@@ -405,6 +402,9 @@
         // Destroys a SurfaceView for a plugin
         void destroySurface(jobject childView);
 
+        // Returns the context (android.content.Context) of the WebView
+        jobject getContext();
+
         bool validNodeAndBounds(Frame* , Node* , const IntRect& );
         // other public functions
     public:
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp
index cd7076d..5ee3e0f 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -54,7 +54,6 @@
     m_hasFocus = false;
     m_isFullScreen = false;
     m_zoomLevel = 0;
-    m_webkitPlugin = NULL;
     m_embeddedView = NULL;
 }
 
@@ -68,9 +67,6 @@
 
     // cleanup any remaining JNI References
     JNIEnv* env = JSC::Bindings::getJNIEnv();
-    if (m_webkitPlugin) {
-        env->DeleteGlobalRef(m_webkitPlugin);
-    }
     if (m_embeddedView) {
         env->DeleteGlobalRef(m_embeddedView);
     }
@@ -83,19 +79,6 @@
     m_core->addPlugin(this);
 }
 
-jobject PluginWidgetAndroid::getJavaPluginInstance() {
-    if (m_webkitPlugin == NULL && m_core != NULL) {
-
-        jobject tempObj = m_core->createPluginJavaInstance(m_pluginView->plugin()->path(),
-                                                           m_pluginView->instance());
-        if (tempObj) {
-            JNIEnv* env = JSC::Bindings::getJNIEnv();
-            m_webkitPlugin = env->NewGlobalRef(tempObj);
-        }
-    }
-    return m_webkitPlugin;
-}
-
 static SkBitmap::Config computeConfig(bool isTransparent) {
     return isTransparent ? SkBitmap::kARGB_8888_Config
                          : SkBitmap::kRGB_565_Config;
@@ -127,9 +110,18 @@
 
         // if the surface does not exist then create a new surface
         } else if(!m_embeddedView) {
-            jobject tempObj = m_core->createSurface(getJavaPluginInstance(),
-                                                    docPoint.x(), docPoint.y(),
-                                                    window->width, window->height);
+
+            WebCore::PluginPackage* pkg = m_pluginView->plugin();
+            NPP instance = m_pluginView->instance();
+
+
+            jobject pluginSurface;
+            pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue,
+                                         static_cast<void*>(&pluginSurface));
+
+            jobject tempObj = m_core->addSurface(pluginSurface,
+                                                 docPoint.x(), docPoint.y(),
+                                                 window->width, window->height);
             if (tempObj) {
                 JNIEnv* env = JSC::Bindings::getJNIEnv();
                 m_embeddedView = env->NewGlobalRef(tempObj);
@@ -437,21 +429,47 @@
 }
 
 void PluginWidgetAndroid::requestFullScreen() {
-    if (m_isFullScreen || !m_webkitPlugin) {
+    if (m_isFullScreen || !m_embeddedView) {
         return;
     }
 
+    // send event to notify plugin of full screen change
+    ANPEvent event;
+    SkANP::InitEvent(&event, kLifecycle_ANPEventType);
+    event.data.lifecycle.action = kEnterFullScreen_ANPLifecycleAction;
+    sendEvent(event);
+
+    // remove the embedded surface from the view hierarchy
+    m_core->destroySurface(m_embeddedView);
+
+    // add the full screen view
     IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y);
-    m_core->showFullScreenPlugin(m_webkitPlugin, m_pluginView->instance(),
+    m_core->showFullScreenPlugin(m_embeddedView, m_pluginView->instance(),
             docPoint.x(), docPoint.y(), m_pluginWindow->width,
             m_pluginWindow->height);
     m_isFullScreen = true;
 }
 
 void PluginWidgetAndroid::exitFullScreen(bool pluginInitiated) {
-    if (m_isFullScreen && pluginInitiated) {
+    if (!m_isFullScreen || !m_embeddedView) {
+        return;
+    }
+
+    // remove the full screen surface from the view hierarchy
+    if (pluginInitiated) {
         m_core->hideFullScreenPlugin();
     }
 
+    // add the embedded view back
+    IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y);
+    m_core->updateSurface(m_embeddedView, docPoint.x(), docPoint.y(),
+                          m_pluginWindow->width, m_pluginWindow->height);
+
+    // send event to notify plugin of full screen change
+    ANPEvent event;
+    SkANP::InitEvent(&event, kLifecycle_ANPEventType);
+    event.data.lifecycle.action = kExitFullScreen_ANPLifecycleAction;
+    sendEvent(event);
+
     m_isFullScreen = false;
 }
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h
index 3a76073..c7cccd1 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.h
+++ b/WebKit/android/plugins/PluginWidgetAndroid.h
@@ -125,13 +125,6 @@
      */
     void setVisibleRects(const ANPRectI rects[], int32_t count);
 
-    /** Returns a java object that implements the WebkitPlugin interface. The
-        implementation is located in the plugin's apk and is described in the
-        apk's manifest file.  For each plugin instance in webkit there is at
-        most one instance of the java object associated with that plugin.
-     */
-    jobject getJavaPluginInstance();
-
     /** Called when a plugin wishes to enter into full screen mode. It invokes
         the plugin's Java class (defined in the plugin's apk manifest), which is
         called asynchronously and provides a View to be displayed full screen.
@@ -164,7 +157,6 @@
     bool                    m_hasFocus;
     bool                    m_isFullScreen;
     float                   m_zoomLevel;
-    jobject                 m_webkitPlugin;
     jobject                 m_embeddedView;
 
     /* We limit the number of rectangles to minimize storage and ensure adequate
diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h
index 1111836..10f7ac9 100644
--- a/WebKit/android/plugins/android_npapi.h
+++ b/WebKit/android/plugins/android_npapi.h
@@ -120,14 +120,18 @@
 #define kSystemInterfaceV0_ANPGetValue      ((NPNVariable)1010)
 #define kEventInterfaceV0_ANPGetValue       ((NPNVariable)1011)
 
-/** queries for which drawing model is desired (for the draw event)
+/** queries for the drawing models supported on this device.
 
-    Should be called inside NPP_New(...)
-
-    NPN_GetValue(inst, ANPSupportedDrawingModel_EnumValue, uint32_t* bits)
+    NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)
  */
 #define kSupportedDrawingModel_ANPGetValue  ((NPNVariable)2000)
 
+/** queries for the context (android.content.Context) in which the plugin resides
+
+    NPN_GetValue(inst, kJavaContext_ANPGetValue, jobject context)
+ */
+#define kJavaContext_ANPGetValue            ((NPNVariable)2001)
+
 ///////////////////////////////////////////////////////////////////////////////
 // NPN_SetValue
 
@@ -147,7 +151,7 @@
     /** Draw into a bitmap from the browser thread in response to a Draw event.
         NPWindow->window is reserved (ignore)
      */
-    kBitmap_ANPDrawingModel  = 0,
+    kBitmap_ANPDrawingModel  = 1 << 0,
     /** Draw into a surface (e.g. raster, openGL, etc.) using the Java surface
         interface. When this model is used the browser will invoke the Java
         class specified in the plugin's apk manifest. From that class the browser
@@ -168,7 +172,7 @@
         unlock the surface in native code without making JNI calls to the Java
         surface object.
      */
-    kSurface_ANPDrawingModel = 0x01,
+    kSurface_ANPDrawingModel = 1 << 1,
 };
 typedef int32_t ANPDrawingModel;
 
@@ -190,6 +194,16 @@
 };
 typedef uint32_t ANPEventFlags;
 
+///////////////////////////////////////////////////////////////////////////////
+// NPP_GetValue
+
+/** Requests that the plugin return a java surface to be displayed. This will
+    only be used if the plugin has choosen the kSurface_ANPDrawingModel.
+
+    NPP_GetValue(inst, kJavaSurface_ANPGetValue, jobject surface)
+ */
+#define kJavaSurface_ANPGetValue            ((NPPVariable)2000)
+
 
 ///////////////////////////////////////////////////////////////////////////////
 // ANDROID INTERFACE DEFINITIONS
@@ -833,28 +847,38 @@
     /** The web view containing this plugin has been paused.  See documentation
         on the android activity lifecycle for more information.
      */
-    kPause_ANPLifecycleAction      = 0,
+    kPause_ANPLifecycleAction            = 0,
     /** The web view containing this plugin has been resumed. See documentation
         on the android activity lifecycle for more information.
      */
-    kResume_ANPLifecycleAction     = 1,
+    kResume_ANPLifecycleAction          = 1,
     /** The plugin has focus and is now the recipient of input events (e.g. key,
         touch, etc.)
      */
-    kGainFocus_ANPLifecycleAction  = 2,
+    kGainFocus_ANPLifecycleAction       = 2,
     /** The plugin has lost focus and will not receive any input events until it
         regains focus. This event is always preceded by a GainFocus action.
      */
-    kLoseFocus_ANPLifecycleAction  = 3,
+    kLoseFocus_ANPLifecycleAction       = 3,
     /** The browser is running low on available memory and is requesting that
         the plugin free any unused/inactive resources to prevent a performance
         degradation.
      */
-    kFreeMemory_ANPLifecycleAction = 4,
+    kFreeMemory_ANPLifecycleAction      = 4,
     /** The page has finished loading. This happens when the page's top level
         frame reports that it has completed loading.
      */
-    kOnLoad_ANPLifecycleAction     = 5,
+    kOnLoad_ANPLifecycleAction          = 5,
+    /** The browser is honoring the plugin's request to go full screen. Upon
+        returning from this event the browser will resize the plugin's java
+        surface to full-screen coordinates.
+     */
+    kEnterFullScreen_ANPLifecycleAction = 6,
+    /** The browser has exited from full screen mode. Immediately prior to
+        sending this event the browser has resized the plugin's java surface to
+        its original coordinates.
+     */
+    kExitFullScreen_ANPLifecycleAction  = 7,
 };
 typedef uint32_t ANPLifecycleAction;