diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp index 7d92f7d80..94b0cfad1 100644 --- a/samples/BrowserPlugin/jni/PluginObject.cpp +++ b/samples/BrowserPlugin/jni/PluginObject.cpp @@ -45,6 +45,27 @@ int SubPlugin::getPluginHeight() { 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 21b7707f7..691234f1e 100644 --- a/samples/BrowserPlugin/jni/PluginObject.h +++ b/samples/BrowserPlugin/jni/PluginObject.h @@ -61,6 +61,10 @@ public: 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 69e485419..f79d9ac14 100644 --- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp +++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp @@ -40,6 +40,7 @@ extern ANPPaintInterfaceV0 gPaintI; 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 @@ static uint32_t getMSecs() { 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(NPP inst) : SurfaceSubPlugin(inst) { } BackgroundPlugin::~BackgroundPlugin() { + setJavaInterface(NULL); surfaceDestroyed(); } diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp index bcca7d0dd..02f768b34 100644 --- a/samples/BrowserPlugin/jni/jni-bridge.cpp +++ b/samples/BrowserPlugin/jni/jni-bridge.cpp @@ -33,6 +33,18 @@ static SurfaceSubPlugin* getPluginObject(int npp) { 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 @@ static jboolean isFixedSurface(JNIEnv* env, jobject thiz, jint npp) { * 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 80f05e4b8..42222228a 100644 --- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp +++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp @@ -50,6 +50,9 @@ PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) { 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 @@ PaintPlugin::~PaintPlugin() { 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 2227a1187..f6608d6b0 100644 --- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp +++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp @@ -45,6 +45,9 @@ extern ANPWindowInterfaceV0 gWindowI; 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(NPP inst) : SurfaceSubPlugin(inst) { } 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 a9fad52d0..e202ad5c5 100644 --- a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java +++ b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java @@ -50,10 +50,14 @@ public class SamplePlugin implements NativePlugin { 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 @@ public class SamplePlugin implements NativePlugin { 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 @@ public class SamplePlugin implements NativePlugin { 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); + } + } } });