Ensure the plugin's native code is never called with an invalid NPP pointer.
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
index 7d92f7d..94b0cfa 100644
--- a/samples/BrowserPlugin/jni/PluginObject.cpp
+++ b/samples/BrowserPlugin/jni/PluginObject.cpp
@@ -45,6 +45,27 @@
     return obj->window->height;
 }
 
+void SurfaceSubPlugin::setJavaInterface(jobject javaInterface) {
+
+    // if one exists then free its reference and notify the object that it is no
+    // longer attached to the native instance
+    JNIEnv* env = NULL;
+    if (m_javaInterface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+
+        // detach the native code from the object
+        jclass javaClass = env->GetObjectClass(m_javaInterface);
+        jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
+        env->CallVoidMethod(m_javaInterface, invalMethod);
+
+        // delete the reference
+        env->DeleteGlobalRef(m_javaInterface);
+        m_javaInterface = NULL;
+    }
+
+    //set the value
+    m_javaInterface = javaInterface;
+}
+
 static void pluginInvalidate(NPObject *obj);
 static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
 static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
index 21b7707..691234f 100644
--- a/samples/BrowserPlugin/jni/PluginObject.h
+++ b/samples/BrowserPlugin/jni/PluginObject.h
@@ -61,6 +61,10 @@
     virtual void surfaceCreated(jobject) = 0;
     virtual void surfaceChanged(int format, int width, int height) = 0;
     virtual void surfaceDestroyed() = 0;
+
+    void setJavaInterface(jobject);
+
+    jobject m_javaInterface;
 };
 
 enum PluginTypes {
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
index 69e4854..f79d9ac 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -40,6 +40,7 @@
 extern ANPSurfaceInterfaceV0   gSurfaceI;
 extern ANPSystemInterfaceV0    gSystemI;
 extern ANPTypefaceInterfaceV0  gTypefaceI;
+extern ANPWindowInterfaceV0    gWindowI;
 
 #define ARRAY_COUNT(array)      (sizeof(array) / sizeof(array[0]))
 
@@ -53,6 +54,9 @@
 
 BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
 
+    // initialize the java interface
+    m_javaInterface = NULL;
+
     // initialize the drawing surface
     m_surface = NULL;
 
@@ -71,6 +75,7 @@
 }
 
 BackgroundPlugin::~BackgroundPlugin() {
+    setJavaInterface(NULL);
     surfaceDestroyed();
 }
 
diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp
index bcca7d0..02f768b 100644
--- a/samples/BrowserPlugin/jni/jni-bridge.cpp
+++ b/samples/BrowserPlugin/jni/jni-bridge.cpp
@@ -33,6 +33,18 @@
     return NULL;
 }
 
+static jboolean javaInit(JNIEnv* env, jobject thiz, jint npp) {
+    SurfaceSubPlugin* obj = getPluginObject(npp);
+
+    if (obj) {
+        jobject globalObject = env->NewGlobalRef(thiz);
+        obj->setJavaInterface(globalObject);
+        return true;
+    } else {
+        return false;
+    }
+}
+
 static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
     SurfaceSubPlugin* obj = getPluginObject(npp);
     jobject globalSurface = env->NewGlobalRef(surface);
@@ -70,6 +82,7 @@
  * JNI registration.
  */
 static JNINativeMethod gJavaSamplePluginMethods[] = {
+    { "nativeJavaInit", "(I)Z", (void*) javaInit },
     { "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated },
     { "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
     { "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
index 80f05e4..4222222 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -50,6 +50,9 @@
     memset(&m_colorToggle, 0, sizeof(m_colorToggle));
     memset(&m_clearSurface,  0, sizeof(m_clearSurface));
 
+    // initialize the java interface
+    m_javaInterface = NULL;
+
     // initialize the drawing surface
     m_surface = NULL;
 
@@ -85,6 +88,7 @@
     gPathI.deletePath(m_touchPath);
     gPaintI.deletePaint(m_paintSurface);
     gPaintI.deletePaint(m_paintButton);
+    setJavaInterface(NULL);
     surfaceDestroyed();
 }
 
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
index 2227a11..f6608d6 100644
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -45,6 +45,9 @@
 
 VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
 
+    // initialize the java interface
+    m_javaInterface = NULL;
+
     // initialize the drawing surface
     m_surface = NULL;
 
@@ -57,6 +60,7 @@
 }
 
 VideoPlugin::~VideoPlugin() {
+    setJavaInterface(NULL);
     surfaceDestroyed();
 }
 
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
index a9fad52..e202ad5 100644
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
@@ -50,10 +50,14 @@
 
     private int npp;
     private Context context;
+    
+    private boolean validNPP = false;
+    private Object nppLock = new Object();
 
     public void initializePlugin(int npp, Context context) {
         this.npp = npp;
         this.context = context;
+        this.validNPP = nativeJavaInit(npp);
     }
 
     public SurfaceDrawingModel getEmbeddedSurface() {
@@ -64,6 +68,14 @@
         return new FullScreenSurface();
     }
 
+    // called by JNI
+    private void invalidateNPP() {
+        synchronized (nppLock) {
+            validNPP = false;
+        }
+    }
+    
+    private native boolean nativeJavaInit(int npp);
     private native void nativeSurfaceCreated(int npp, View surfaceView);
     private native void nativeSurfaceChanged(int npp, int format, int width, int height);
     private native void nativeSurfaceDestroyed(int npp);
@@ -85,15 +97,27 @@
             view.getHolder().addCallback(new Callback() {
 
                 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-                    nativeSurfaceChanged(npp, format, width, height);
+                    synchronized (nppLock) {
+                        if (validNPP) {
+                            nativeSurfaceChanged(npp, format, width, height);
+                        }
+                    }
                 }
 
                 public void surfaceCreated(SurfaceHolder holder) {
-                    nativeSurfaceCreated(npp, view);
+                    synchronized (nppLock) {
+                        if (validNPP) {
+                            nativeSurfaceCreated(npp, view);
+                        }
+                    }
                 }
 
                 public void surfaceDestroyed(SurfaceHolder holder) {
-                    nativeSurfaceDestroyed(npp);
+                    synchronized (nppLock) {
+                        if (validNPP) {
+                            nativeSurfaceDestroyed(npp);
+                        }
+                    }
                 }
             });