Adding a full screen video sample plugin. Also cleaned up surface plugins to use the provided JavaVM.
diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
index cbd8a15..b93e4a6 100644
--- a/samples/BrowserPlugin/jni/Android.mk
+++ b/samples/BrowserPlugin/jni/Android.mk
@@ -35,6 +35,7 @@
 	background/BackgroundPlugin.cpp \
 	form/FormPlugin.cpp \
 	paint/PaintPlugin.cpp \
+	video/VideoPlugin.cpp \
 	jni-bridge.cpp \
 
 LOCAL_C_INCLUDES += \
@@ -45,6 +46,7 @@
 	$(LOCAL_PATH)/background \
 	$(LOCAL_PATH)/form \
 	$(LOCAL_PATH)/paint \
+	$(LOCAL_PATH)/video \
 	external/webkit/WebCore/bridge \
 	external/webkit/WebCore/plugins \
 	external/webkit/WebCore/platform/android/JavaVM \
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
index 61486d5..deb60ea 100644
--- a/samples/BrowserPlugin/jni/PluginObject.h
+++ b/samples/BrowserPlugin/jni/PluginObject.h
@@ -55,7 +55,7 @@
     SurfaceSubPlugin(NPP inst) : SubPlugin(inst) {}
     virtual ~SurfaceSubPlugin() {}
     virtual bool isFixedSurface() = 0;
-    virtual void surfaceCreated(JNIEnv*, jobject) = 0;
+    virtual void surfaceCreated(jobject) = 0;
     virtual void surfaceChanged(int format, int width, int height) = 0;
     virtual void surfaceDestroyed() = 0;
 };
@@ -67,6 +67,7 @@
     kForm_PluginType       = 4,
     kText_PluginType       = 5,
     kPaint_PluginType      = 6,
+    kVideo_PluginType      = 7,
 };
 typedef uint32_t PluginType;
 
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
index 2a65b4f..af518a9 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -54,7 +54,6 @@
 
     // initialize the drawing surface
     m_surface = NULL;
-    m_vm = NULL;
 
     //initialize bitmap transparency variables
     mFinishedStageOne   = false;
@@ -69,7 +68,9 @@
     test_javascript();
 }
 
-BackgroundPlugin::~BackgroundPlugin() { }
+BackgroundPlugin::~BackgroundPlugin() {
+    surfaceDestroyed();
+}
 
 bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) {
     return (model == kSurface_ANPDrawingModel);
@@ -79,9 +80,8 @@
     return false;
 }
 
-void BackgroundPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
-    env->GetJavaVM(&m_vm);
-    m_surface = env->NewGlobalRef(surface);
+void BackgroundPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
 }
 
 void BackgroundPlugin::surfaceChanged(int format, int width, int height) {
@@ -90,7 +90,7 @@
 
 void BackgroundPlugin::surfaceDestroyed() {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         env->DeleteGlobalRef(m_surface);
         m_surface = NULL;
     }
@@ -119,7 +119,7 @@
     // lock the surface
     ANPBitmap bitmap;
     JNIEnv* env = NULL;
-    if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
         !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
         gLogI.log(inst(), kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
         return;
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
index 3b9c7ba..d370810 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
@@ -34,7 +34,7 @@
     virtual ~BackgroundPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
     virtual int16 handleEvent(const ANPEvent* evt);
-    virtual void surfaceCreated(JNIEnv* env, jobject surface);
+    virtual void surfaceCreated(jobject surface);
     virtual void surfaceChanged(int format, int width, int height);
     virtual void surfaceDestroyed();
     virtual bool isFixedSurface();
@@ -55,7 +55,6 @@
     void drawPlugin(int surfaceWidth, int surfaceHeight);
 
     jobject     m_surface;
-    JavaVM*     m_vm;
 
     void test_logging();
     void test_timers();
diff --git a/samples/BrowserPlugin/jni/hello-jni.cpp b/samples/BrowserPlugin/jni/hello-jni.cpp
deleted file mode 100644
index 0789b7e..0000000
--- a/samples/BrowserPlugin/jni/hello-jni.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-#include <string.h>
-#include <jni.h>
-#include <JNIHelp.h>
-#include <utils/Log.h>
-
-#define EXPORT __attribute__((visibility("default")))
-
-static jstring stringFromJNI( JNIEnv* env, jobject thiz )
-{
-    return env->NewStringUTF("Hello from JNI !");
-}
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gJavaSamplePluginStubMethods[] = {
-    { "nativeStringFromJNI", "()Ljava/lang/String;", (void*) stringFromJNI },
-};
-
-EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-
-    JNIEnv* env = NULL;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        return -1;
-    }
-
-    jniRegisterNativeMethods(env, "com/android/sampleplugin/SamplePluginStub",
-                             gJavaSamplePluginStubMethods, NELEM(gJavaSamplePluginStubMethods));
-
-    return JNI_VERSION_1_4;
-}
diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp
index 45ecd54..22e76da 100644
--- a/samples/BrowserPlugin/jni/jni-bridge.cpp
+++ b/samples/BrowserPlugin/jni/jni-bridge.cpp
@@ -35,12 +35,8 @@
 
 static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
     SurfaceSubPlugin* obj = getPluginObject(npp);
-
-    //TODO why is this VM different from the one in NP_INIT...
-    JavaVM* vm = NULL;
-    env->GetJavaVM(&vm);
-
-    obj->surfaceCreated(env, surface);
+    jobject globalSurface = env->NewGlobalRef(surface);
+    obj->surfaceCreated(globalSurface);
 }
 
 static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp
index d00091f..6f0ed96 100644
--- a/samples/BrowserPlugin/jni/main.cpp
+++ b/samples/BrowserPlugin/jni/main.cpp
@@ -33,8 +33,11 @@
 #include "BackgroundPlugin.h"
 #include "FormPlugin.h"
 #include "PaintPlugin.h"
+#include "VideoPlugin.h"
 
 NPNetscapeFuncs* browser;
+JavaVM* gVM;
+
 #define EXPORT __attribute__((visibility("default")))
 
 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
@@ -128,6 +131,10 @@
         }
     }
 
+    // store the JavaVM for the plugin
+    JNIEnv* env = (JNIEnv*)java_env;
+    env->GetJavaVM(&gVM);
+
     return NPERR_NO_ERROR;
 }
 
@@ -220,6 +227,10 @@
                 obj->pluginType = kPaint_PluginType;
                 obj->activePlugin = new PaintPlugin(instance);
             }
+            else if (!strcmp(argv[i], "Video")) {
+                obj->pluginType = kVideo_PluginType;
+                obj->activePlugin = new VideoPlugin(instance);
+            }
             gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
             break;
         }
diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h
index 8ad2cce..5906b0b 100644
--- a/samples/BrowserPlugin/jni/main.h
+++ b/samples/BrowserPlugin/jni/main.h
@@ -30,3 +30,4 @@
 #include "ANPSurface_npapi.h"
 
 extern NPNetscapeFuncs* browser;
+extern JavaVM* gVM;
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
index 5b00dba..11f00fe 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -52,7 +52,6 @@
 
     // initialize the drawing surface
     m_surface = NULL;
-    m_vm = NULL;
 
     // initialize the path
     m_touchPath = gPathI.newPath();
@@ -97,7 +96,7 @@
 
     ANPBitmap bitmap;
     JNIEnv* env = NULL;
-    if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
         !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
             return NULL;
         }
@@ -132,7 +131,7 @@
 
 void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         gSurfaceI.unlock(env, m_surface);
     }
     gCanvasI.deleteCanvas(canvas);
@@ -216,9 +215,8 @@
     return true;
 }
 
-void PaintPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
-    env->GetJavaVM(&m_vm);
-    m_surface = env->NewGlobalRef(surface);
+void PaintPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
     drawCleanPlugin();
 }
 
@@ -235,7 +233,7 @@
 }
 void PaintPlugin::surfaceDestroyed() {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         env->DeleteGlobalRef(m_surface);
         m_surface = NULL;
     }
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
index 8ff561c..a917ffb 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
@@ -35,7 +35,7 @@
     virtual ~PaintPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
     virtual int16 handleEvent(const ANPEvent* evt);
-    virtual void surfaceCreated(JNIEnv* env, jobject surface);
+    virtual void surfaceCreated(jobject surface);
     virtual void surfaceChanged(int format, int width, int height);
     virtual void surfaceDestroyed();
     virtual bool isFixedSurface();
@@ -55,7 +55,6 @@
     bool        m_isTouchActive;
     bool        m_isTouchCurrentInput;
 
-    JavaVM*     m_vm;
     jobject     m_surface;
     ANPPath*    m_touchPath;
 
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
new file mode 100644
index 0000000..2609af6
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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 APPLE COMPUTER, INC. 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.
+ */
+
+#include "VideoPlugin.h"
+#include "android_npapi.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*        browser;
+extern ANPBitmapInterfaceV0    gBitmapI;
+extern ANPCanvasInterfaceV0    gCanvasI;
+extern ANPLogInterfaceV0       gLogI;
+extern ANPPaintInterfaceV0     gPaintI;
+extern ANPSurfaceInterfaceV0   gSurfaceI;
+extern ANPTypefaceInterfaceV0  gTypefaceI;
+extern ANPWindowInterfaceV0  gWindowI;
+
+///////////////////////////////////////////////////////////////////////////////
+
+VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
+
+    // initialize the drawing surface
+    m_surface = NULL;
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(inst, kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+VideoPlugin::~VideoPlugin() {
+    surfaceDestroyed();
+}
+
+bool VideoPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kSurface_ANPDrawingModel);
+}
+
+bool VideoPlugin::isFixedSurface() {
+    return true;
+}
+
+void VideoPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
+    drawPlugin();
+}
+
+void VideoPlugin::surfaceChanged(int format, int width, int height) {
+    gLogI.log(inst(), kDebug_ANPLogType, "----%p SurfaceChanged Event: %d",
+              inst(), format);
+    drawPlugin();
+}
+
+void VideoPlugin::surfaceDestroyed() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+void VideoPlugin::drawPlugin() {
+
+    ANPBitmap bitmap;
+    JNIEnv* env = NULL;
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+        !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
+            gLogI.log(inst(), kError_ANPLogType, "----%p Unable to Lock Surface", inst());
+            return;
+    }
+
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    // get the plugin's dimensions according to the DOM
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    const int pW = obj->window->width;
+    const int pH = obj->window->height;
+
+    // compare DOM dimensions to the plugin's surface dimensions
+    if (pW != bitmap.width || pH != bitmap.height)
+        gLogI.log(inst(), kError_ANPLogType,
+                  "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
+                  inst(), pW, pH, bitmap.width, bitmap.height);
+
+    // set constants
+    const int fontSize = 16;
+    const int leftMargin = 10;
+
+    gCanvasI.drawColor(canvas, 0xFFCDCDCD);
+
+    ANPPaint* paint = gPaintI.newPaint();
+    gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(paint, 0xFFFF0000);
+    gPaintI.setTextSize(paint, fontSize);
+
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(paint, tf);
+    gTypefaceI.unref(tf);
+
+    ANPFontMetrics fm;
+    gPaintI.getFontMetrics(paint, &fm);
+
+    gPaintI.setColor(paint, 0xFF0000FF);
+    const char c[] = "Touch anywhere on the plugin to begin video playback!";
+    gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
+
+    // clean up variables and unlock the surface
+    gPaintI.deletePaint(paint);
+    gCanvasI.deleteCanvas(canvas);
+    gSurfaceI.unlock(env, m_surface);
+}
+
+int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
+            break;
+        case kTouch_ANPEventType:
+            if (kDown_ANPTouchAction == evt->data.touch.action) {
+                gLogI.log(inst(), kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
+                gWindowI.requestFullScreen(inst());
+            }
+            return 1;
+        case kKey_ANPEventType:
+            gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
+            break;
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h
new file mode 100644
index 0000000..dd6859d
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h
@@ -0,0 +1,48 @@
+/*
+ * 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 APPLE COMPUTER, INC. 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.
+ */
+
+#include "PluginObject.h"
+
+#ifndef videoPlugin__DEFINED
+#define videoPlugin__DEFINED
+
+class VideoPlugin : public SurfaceSubPlugin {
+public:
+    VideoPlugin(NPP inst);
+    virtual ~VideoPlugin();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual void surfaceCreated(jobject surface);
+    virtual void surfaceChanged(int format, int width, int height);
+    virtual void surfaceDestroyed();
+    virtual bool isFixedSurface();
+
+private:
+    void drawPlugin();
+
+    jobject     m_surface;
+};
+
+#endif // videoPlugin__DEFINED