am bd2ced11: am 51cce58c: Ensure the plugin\'s native code is never called with an invalid NPP pointer.
Merge commit 'bd2ced1184a498fe5e6d93e780707e99971a0216' * commit 'bd2ced1184a498fe5e6d93e780707e99971a0216': Ensure the plugin's native code is never called with an invalid NPP pointer.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,9 +51,13 @@ 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,16 +97,28 @@ public class SamplePlugin implements NativePlugin {
|
||||
view.getHolder().addCallback(new Callback() {
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceChanged(npp, format, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceCreated(npp, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceDestroyed(npp);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO provide way for native plugin code to reset the size
|
||||
|
||||
Reference in New Issue
Block a user