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);
+ }
+ }
}
});