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;
|
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 void pluginInvalidate(NPObject *obj);
|
||||||
static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
|
static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
|
||||||
static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
|
static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
virtual void surfaceCreated(jobject) = 0;
|
virtual void surfaceCreated(jobject) = 0;
|
||||||
virtual void surfaceChanged(int format, int width, int height) = 0;
|
virtual void surfaceChanged(int format, int width, int height) = 0;
|
||||||
virtual void surfaceDestroyed() = 0;
|
virtual void surfaceDestroyed() = 0;
|
||||||
|
|
||||||
|
void setJavaInterface(jobject);
|
||||||
|
|
||||||
|
jobject m_javaInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PluginTypes {
|
enum PluginTypes {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ extern ANPPaintInterfaceV0 gPaintI;
|
|||||||
extern ANPSurfaceInterfaceV0 gSurfaceI;
|
extern ANPSurfaceInterfaceV0 gSurfaceI;
|
||||||
extern ANPSystemInterfaceV0 gSystemI;
|
extern ANPSystemInterfaceV0 gSystemI;
|
||||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||||
|
extern ANPWindowInterfaceV0 gWindowI;
|
||||||
|
|
||||||
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
@@ -53,6 +54,9 @@ static uint32_t getMSecs() {
|
|||||||
|
|
||||||
BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
||||||
|
|
||||||
|
// initialize the java interface
|
||||||
|
m_javaInterface = NULL;
|
||||||
|
|
||||||
// initialize the drawing surface
|
// initialize the drawing surface
|
||||||
m_surface = NULL;
|
m_surface = NULL;
|
||||||
|
|
||||||
@@ -71,6 +75,7 @@ BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BackgroundPlugin::~BackgroundPlugin() {
|
BackgroundPlugin::~BackgroundPlugin() {
|
||||||
|
setJavaInterface(NULL);
|
||||||
surfaceDestroyed();
|
surfaceDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,18 @@ static SurfaceSubPlugin* getPluginObject(int npp) {
|
|||||||
return NULL;
|
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) {
|
static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
|
||||||
SurfaceSubPlugin* obj = getPluginObject(npp);
|
SurfaceSubPlugin* obj = getPluginObject(npp);
|
||||||
jobject globalSurface = env->NewGlobalRef(surface);
|
jobject globalSurface = env->NewGlobalRef(surface);
|
||||||
@@ -70,6 +82,7 @@ static jboolean isFixedSurface(JNIEnv* env, jobject thiz, jint npp) {
|
|||||||
* JNI registration.
|
* JNI registration.
|
||||||
*/
|
*/
|
||||||
static JNINativeMethod gJavaSamplePluginMethods[] = {
|
static JNINativeMethod gJavaSamplePluginMethods[] = {
|
||||||
|
{ "nativeJavaInit", "(I)Z", (void*) javaInit },
|
||||||
{ "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated },
|
{ "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated },
|
||||||
{ "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
|
{ "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
|
||||||
{ "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
|
{ "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
|||||||
memset(&m_colorToggle, 0, sizeof(m_colorToggle));
|
memset(&m_colorToggle, 0, sizeof(m_colorToggle));
|
||||||
memset(&m_clearSurface, 0, sizeof(m_clearSurface));
|
memset(&m_clearSurface, 0, sizeof(m_clearSurface));
|
||||||
|
|
||||||
|
// initialize the java interface
|
||||||
|
m_javaInterface = NULL;
|
||||||
|
|
||||||
// initialize the drawing surface
|
// initialize the drawing surface
|
||||||
m_surface = NULL;
|
m_surface = NULL;
|
||||||
|
|
||||||
@@ -85,6 +88,7 @@ PaintPlugin::~PaintPlugin() {
|
|||||||
gPathI.deletePath(m_touchPath);
|
gPathI.deletePath(m_touchPath);
|
||||||
gPaintI.deletePaint(m_paintSurface);
|
gPaintI.deletePaint(m_paintSurface);
|
||||||
gPaintI.deletePaint(m_paintButton);
|
gPaintI.deletePaint(m_paintButton);
|
||||||
|
setJavaInterface(NULL);
|
||||||
surfaceDestroyed();
|
surfaceDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ extern ANPWindowInterfaceV0 gWindowI;
|
|||||||
|
|
||||||
VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
||||||
|
|
||||||
|
// initialize the java interface
|
||||||
|
m_javaInterface = NULL;
|
||||||
|
|
||||||
// initialize the drawing surface
|
// initialize the drawing surface
|
||||||
m_surface = NULL;
|
m_surface = NULL;
|
||||||
|
|
||||||
@@ -57,6 +60,7 @@ VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VideoPlugin::~VideoPlugin() {
|
VideoPlugin::~VideoPlugin() {
|
||||||
|
setJavaInterface(NULL);
|
||||||
surfaceDestroyed();
|
surfaceDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,9 +51,13 @@ public class SamplePlugin implements NativePlugin {
|
|||||||
private int npp;
|
private int npp;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
|
private boolean validNPP = false;
|
||||||
|
private Object nppLock = new Object();
|
||||||
|
|
||||||
public void initializePlugin(int npp, Context context) {
|
public void initializePlugin(int npp, Context context) {
|
||||||
this.npp = npp;
|
this.npp = npp;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.validNPP = nativeJavaInit(npp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SurfaceDrawingModel getEmbeddedSurface() {
|
public SurfaceDrawingModel getEmbeddedSurface() {
|
||||||
@@ -64,6 +68,14 @@ public class SamplePlugin implements NativePlugin {
|
|||||||
return new FullScreenSurface();
|
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 nativeSurfaceCreated(int npp, View surfaceView);
|
||||||
private native void nativeSurfaceChanged(int npp, int format, int width, int height);
|
private native void nativeSurfaceChanged(int npp, int format, int width, int height);
|
||||||
private native void nativeSurfaceDestroyed(int npp);
|
private native void nativeSurfaceDestroyed(int npp);
|
||||||
@@ -85,16 +97,28 @@ public class SamplePlugin implements NativePlugin {
|
|||||||
view.getHolder().addCallback(new Callback() {
|
view.getHolder().addCallback(new Callback() {
|
||||||
|
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
synchronized (nppLock) {
|
||||||
|
if (validNPP) {
|
||||||
nativeSurfaceChanged(npp, format, width, height);
|
nativeSurfaceChanged(npp, format, width, height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
synchronized (nppLock) {
|
||||||
|
if (validNPP) {
|
||||||
nativeSurfaceCreated(npp, view);
|
nativeSurfaceCreated(npp, view);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
synchronized (nppLock) {
|
||||||
|
if (validNPP) {
|
||||||
nativeSurfaceDestroyed(npp);
|
nativeSurfaceDestroyed(npp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO provide way for native plugin code to reset the size
|
// TODO provide way for native plugin code to reset the size
|
||||||
|
|||||||
Reference in New Issue
Block a user