From: rikky Date: Mon, 23 Apr 2012 18:46:09 +0000 (+0000) Subject: Fix:Android:Fix global JNI references (fix crashes with target API 15) X-Git-Tag: navit-0.5.0.5194svn~159 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06f522dc768c74e92bb557b58da4e22a01558ec8;p=profile%2Fivi%2Fnavit.git Fix:Android:Fix global JNI references (fix crashes with target API 15) git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@5036 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- diff --git a/navit/navit/android.c b/navit/navit/android.c index 1107f60..8e320bb 100644 --- a/navit/navit/android.c +++ b/navit/navit/android.c @@ -34,7 +34,7 @@ android_find_class_global(char *name, jclass *ret) dbg(0,"Failed to get Class %s\n",name); return 0; } - (*jnienv)->NewGlobalRef(jnienv, *ret); + *ret = (*jnienv)->NewGlobalRef(jnienv, *ret); return 1; } @@ -58,10 +58,9 @@ Java_org_navitproject_navit_Navit_NavitMain( JNIEnv* env, jobject thiz, jobject android_version=version; __android_log_print(ANDROID_LOG_ERROR,"test","called"); jnienv=env; - android_activity=activity; - (*jnienv)->NewGlobalRef(jnienv, activity); + android_activity = (*jnienv)->NewGlobalRef(jnienv, activity); langstr=(*env)->GetStringUTFChars(env, lang, NULL); - dbg(0,"enter env=%p thiz=%p activity=%p lang=%s version=%d\n",env,thiz,activity,langstr,version); + dbg(0,"enter env=%p thiz=%p activity=%p lang=%s version=%d\n",env,thiz,android_activity,langstr,version); setenv("LANG",langstr,1); (*env)->ReleaseStringUTFChars(env, lang, langstr); @@ -119,12 +118,11 @@ Java_org_navitproject_navit_NavitGraphics_KeypressCallback( JNIEnv* env, jobject } JNIEXPORT void JNICALL -Java_org_navitproject_navit_NavitTimeout_TimeoutCallback( JNIEnv* env, jobject thiz, int delete, int id) +Java_org_navitproject_navit_NavitTimeout_TimeoutCallback( JNIEnv* env, jobject thiz, int id) { - dbg(1,"enter %p %d %p\n",thiz, delete, (void *)id); - callback_call_0((struct callback *)id); - if (delete) - (*jnienv)->DeleteGlobalRef(jnienv, thiz); + void (*event_handler)(void *) = *(void **)id; + dbg(0,"enter %p %p\n",thiz, (void *)id); + event_handler((void*)id); } JNIEXPORT void JNICALL @@ -204,7 +202,8 @@ Java_org_navitproject_navit_NavitGraphics_CallbackSearchResultList( JNIEnv* env, my_jni_object.jo=thiz; my_jni_object.jm=aMethodID; - /* TODO (rikky#1#): does return nothing yet, also should use a generic callback instead of jni_object */ ret=search_by_address(sl,search_string,partial,&my_jni_object); + /* TODO (rikky#1#): does return nothing yet, also should use a generic callback instead of jni_object */ + ret=search_by_address(sl,search_string,partial,&my_jni_object); search_list_destroy(sl); dbg(0,"ret=%p\n",ret); diff --git a/navit/navit/android/src/org/navitproject/navit/NavitTimeout.java b/navit/navit/android/src/org/navitproject/navit/NavitTimeout.java index 3590e8b..b70d8a1 100644 --- a/navit/navit/android/src/org/navitproject/navit/NavitTimeout.java +++ b/navit/navit/android/src/org/navitproject/navit/NavitTimeout.java @@ -34,11 +34,11 @@ public class NavitTimeout implements Runnable { private boolean event_multi; private int event_callbackid; private int event_timeout; - public native void TimeoutCallback(int del, int id); + public native void TimeoutCallback(int id); - NavitTimeout(int timeout, boolean multi, int callbackid) + NavitTimeout(int timeout, boolean multi, int callbackid) { - event_timeout=timeout; + event_timeout=timeout; event_multi=multi; event_callbackid=callbackid; handler.postDelayed(this, event_timeout); @@ -47,9 +47,8 @@ public class NavitTimeout implements Runnable { // Log.e("Navit","Handle Event"); if (event_multi) { handler.postDelayed(this, event_timeout); - TimeoutCallback(0, event_callbackid); - } else - TimeoutCallback(1, event_callbackid); + } + TimeoutCallback(event_callbackid); } public void remove() { diff --git a/navit/navit/graphics/android/graphics_android.c b/navit/navit/graphics/android/graphics_android.c index c15ac03..69c8b2c 100644 --- a/navit/navit/graphics/android/graphics_android.c +++ b/navit/navit/graphics/android/graphics_android.c @@ -90,7 +90,7 @@ find_class_global(char *name, jclass *ret) dbg(0,"Failed to get Class %s\n",name); return 0; } - (*jnienv)->NewGlobalRef(jnienv, *ret); + *ret = (*jnienv)->NewGlobalRef(jnienv, *ret); return 1; } @@ -203,11 +203,12 @@ static struct graphics_image_priv * image_new(struct graphics_priv *gra, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot, int rotation) { struct graphics_image_priv* ret = NULL; - + if ( !g_hash_table_lookup_extended( image_cache_hash, path, NULL, (gpointer)&ret) ) { ret=g_new0(struct graphics_image_priv, 1); jstring string; + jclass localBitmap = NULL; int id; dbg(1,"enter %s\n",path); @@ -215,7 +216,7 @@ image_new(struct graphics_priv *gra, struct graphics_image_methods *meth, char * jstring a=(*jnienv)->NewStringUTF(jnienv, "drawable"); char *path_noext=g_strdup(path+13); char *pos=strrchr(path_noext, '.'); - if (pos) + if (pos) *pos='\0'; dbg(1,"path_noext=%s\n",path_noext); string = (*jnienv)->NewStringUTF(jnienv, path_noext); @@ -223,16 +224,16 @@ image_new(struct graphics_priv *gra, struct graphics_image_methods *meth, char * id=(*jnienv)->CallIntMethod(jnienv, gra->Resources, gra->Resources_getIdentifier, string, a, gra->packageName); dbg(1,"id=%d\n",id); if (id) - ret->Bitmap=(*jnienv)->CallStaticObjectMethod(jnienv, gra->BitmapFactoryClass, gra->BitmapFactory_decodeResource, gra->Resources, id); + localBitmap=(*jnienv)->CallStaticObjectMethod(jnienv, gra->BitmapFactoryClass, gra->BitmapFactory_decodeResource, gra->Resources, id); (*jnienv)->DeleteLocalRef(jnienv, a); } else { string = (*jnienv)->NewStringUTF(jnienv, path); - ret->Bitmap=(*jnienv)->CallStaticObjectMethod(jnienv, gra->BitmapFactoryClass, gra->BitmapFactory_decodeFile, string); + localBitmap=(*jnienv)->CallStaticObjectMethod(jnienv, gra->BitmapFactoryClass, gra->BitmapFactory_decodeFile, string); } - dbg(1,"result=%p\n",ret->Bitmap); - if (ret->Bitmap) { - (*jnienv)->NewGlobalRef(jnienv, ret->Bitmap); - (*jnienv)->DeleteLocalRef(jnienv, ret->Bitmap); + dbg(1,"result=%p\n",localBitmap); + if (localBitmap) { + ret->Bitmap = (*jnienv)->NewGlobalRef(jnienv, localBitmap); + (*jnienv)->DeleteLocalRef(jnienv, localBitmap); ret->width=(*jnienv)->CallIntMethod(jnienv, ret->Bitmap, gra->Bitmap_getWidth); ret->height=(*jnienv)->CallIntMethod(jnienv, ret->Bitmap, gra->Bitmap_getHeight); dbg(1,"w=%d h=%d for %s\n",ret->width,ret->height,path); @@ -531,11 +532,11 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s return 0; if (!find_method(ret->ContextClass, "getResources", "()Landroid/content/res/Resources;", &ret->Context_getResources)) return 0; - + ret->Resources=(*jnienv)->CallObjectMethod(jnienv, android_activity, ret->Context_getResources); if (ret->Resources) - (*jnienv)->NewGlobalRef(jnienv, ret->Resources); + ret->Resources = (*jnienv)->NewGlobalRef(jnienv, ret->Resources); if (!find_class_global("android/content/res/Resources", &ret->ResourcesClass)) return 0; if (!find_method(ret->ResourcesClass, "getIdentifier", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", &ret->Resources_getIdentifier)) @@ -544,7 +545,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s if (!find_method(ret->ContextClass, "getPackageName", "()Ljava/lang/String;", &Context_getPackageName)) return 0; ret->packageName=(*jnienv)->CallObjectMethod(jnienv, android_activity, Context_getPackageName); - (*jnienv)->NewGlobalRef(jnienv, ret->packageName); + ret->packageName=(*jnienv)->NewGlobalRef(jnienv, ret->packageName); if (!find_class_global("org/navitproject/navit/NavitGraphics", &ret->NavitGraphicsClass)) return 0; @@ -558,8 +559,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s ret->NavitGraphics=(*jnienv)->NewObject(jnienv, ret->NavitGraphicsClass, cid, android_activity, parent ? parent->NavitGraphics : NULL, pnt ? pnt->x:0 , pnt ? pnt->y:0, w, h, alpha, wraparound, use_camera); dbg(0,"result=%p\n",ret->NavitGraphics); if (ret->NavitGraphics) - (*jnienv)->NewGlobalRef(jnienv, ret->NavitGraphics); - + ret->NavitGraphics = (*jnienv)->NewGlobalRef(jnienv, ret->NavitGraphics); /* Create a single global Paint, otherwise android will quickly run out * of global refs.*/ @@ -568,7 +568,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s dbg(0,"result=%p\n",ret->Paint); if (ret->Paint) - (*jnienv)->NewGlobalRef(jnienv, ret->Paint); + ret->Paint = (*jnienv)->NewGlobalRef(jnienv, ret->Paint); cid = (*jnienv)->GetMethodID(jnienv, ret->NavitGraphicsClass, "setSizeChangedCallback", "(I)V"); if (cid == NULL) { @@ -647,7 +647,6 @@ graphics_android_disable_suspend(struct window *win) } - static struct graphics_priv * graphics_android_new(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl) { @@ -694,12 +693,12 @@ overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct poin static void event_android_main_loop_run(void) { - dbg(0,"enter\n"); + dbg(0,"enter\n"); } static void event_android_main_loop_quit(void) { - dbg(0,"enter\n"); + dbg(0,"enter\n"); (*jnienv)->CallVoidMethod(jnienv, android_activity, Navit_exit); } @@ -746,7 +745,7 @@ event_android_add_watch(void *h, enum event_watch_cond cond, struct callback *cb ret=(*jnienv)->NewObject(jnienv, NavitWatchClass, NavitWatch_init, (int)do_poll, (int) h, (int) cond, (int)cb); dbg(0,"result for %p,%d,%p=%p\n",h,cond,cb,ret); if (ret) - (*jnienv)->NewGlobalRef(jnienv, ret); + ret = (*jnienv)->NewGlobalRef(jnienv, ret); return (struct event_watch *)ret; } @@ -761,28 +760,44 @@ event_android_remove_watch(struct event_watch *ev) } } -static struct event_timeout * -event_android_add_timeout(int timeout, int multi, struct callback *cb) +struct event_timeout { - jobject ret; - ret=(*jnienv)->NewObject(jnienv, NavitTimeoutClass, NavitTimeout_init, timeout, multi, (int)cb); - dbg(1,"result for %d,%d,%p=%p\n",timeout,multi,cb,ret); - if (ret) - (*jnienv)->NewGlobalRef(jnienv, ret); - return (struct event_timeout *)ret; -} + void (*handle_timeout)(struct event_timeout *priv); + jobject jni_timeout; + int multi; + struct callback *cb; +}; static void -event_android_remove_timeout(struct event_timeout *to) +event_android_remove_timeout(struct event_timeout *priv) { - dbg(1,"enter %p\n",to); - if (to) { - jobject obj=(jobject )to; - (*jnienv)->CallVoidMethod(jnienv, obj, NavitTimeout_remove); - (*jnienv)->DeleteGlobalRef(jnienv, obj); + if (priv && priv->jni_timeout) { + (*jnienv)->CallVoidMethod(jnienv, priv->jni_timeout, NavitTimeout_remove); + (*jnienv)->DeleteGlobalRef(jnienv, priv->jni_timeout); + priv->jni_timeout = NULL; } } +static void event_android_handle_timeout(struct event_timeout *priv) +{ + callback_call_0(priv->cb); + if (!priv->multi) + event_android_remove_timeout(priv); +} + +static struct event_timeout * +event_android_add_timeout(int timeout, int multi, struct callback *cb) +{ + struct event_timeout *ret = g_new0(struct event_timeout, 1); + ret->cb = cb; + ret->multi = multi; + ret->handle_timeout = event_android_handle_timeout; + ret->jni_timeout = (*jnienv)->NewObject(jnienv, NavitTimeoutClass, NavitTimeout_init, timeout, multi, (int)ret); + if (ret->jni_timeout) + ret->jni_timeout = (*jnienv)->NewGlobalRef(jnienv, ret->jni_timeout); + return ret; +} + static struct event_idle * event_android_add_idle(int priority, struct callback *cb) @@ -793,7 +808,7 @@ event_android_add_idle(int priority, struct callback *cb) ret=(*jnienv)->NewObject(jnienv, NavitIdleClass, NavitIdle_init, (int)cb); dbg(1,"result for %p=%p\n",cb,ret); if (ret) - (*jnienv)->NewGlobalRef(jnienv, ret); + ret = (*jnienv)->NewGlobalRef(jnienv, ret); return (struct event_idle *)ret; #endif return (struct event_idle *)event_android_add_timeout(1, 1, cb); diff --git a/navit/navit/plugin/pedestrian/pedestrian.c b/navit/navit/plugin/pedestrian/pedestrian.c index 166db1f..bfd14bd 100644 --- a/navit/navit/plugin/pedestrian/pedestrian.c +++ b/navit/navit/plugin/pedestrian/pedestrian.c @@ -1252,11 +1252,10 @@ pedestrian_navit_init(struct navit *nav) if (cid) { cb=callback_new_1(callback_cast(android_sensors), nav); navitsensors=(*jnienv)->NewObject(jnienv, navitsensorsclass, cid, android_activity, cb); - dbg(0,"object=%p\n",navitsensors); - if (navitsensors) - (*jnienv)->NewGlobalRef(jnienv, navitsensors); + dbg(0,"object=%p\n",navitsensors); + if (navitsensors) + navitsensors = (*jnienv)->NewGlobalRef(jnienv, navitsensors); } - } #endif pedestrian_data.nav=nav; diff --git a/navit/navit/speech/android/speech_android.c b/navit/navit/speech/android/speech_android.c index d383483..c7d056b 100644 --- a/navit/navit/speech/android/speech_android.c +++ b/navit/navit/speech/android/speech_android.c @@ -102,23 +102,23 @@ speech_android_init(struct speech_priv *ret) if (!android_find_class_global(class, &ret->NavitSpeechClass)) { dbg(0,"No class found\n"); - return 0; + return 0; + } + dbg(0,"at 3\n"); + cid = (*jnienv)->GetMethodID(jnienv, ret->NavitSpeechClass, "", "(Lorg/navitproject/navit/Navit;)V"); + if (cid == NULL) { + dbg(0,"no method found\n"); + return 0; /* exception thrown */ } - dbg(0,"at 3\n"); - cid = (*jnienv)->GetMethodID(jnienv, ret->NavitSpeechClass, "", "(Lorg/navitproject/navit/Navit;)V"); - if (cid == NULL) { - dbg(0,"no method found\n"); - return 0; /* exception thrown */ - } if (!android_find_method(ret->NavitSpeechClass, "say", "(Ljava/lang/String;)V", &ret->NavitSpeech_say)) - return 0; - dbg(0,"at 4 android_activity=%p\n",android_activity); - ret->NavitSpeech=(*jnienv)->NewObject(jnienv, ret->NavitSpeechClass, cid, android_activity); - dbg(0,"result=%p\n",ret->NavitSpeech); + return 0; + dbg(0,"at 4 android_activity=%p\n",android_activity); + ret->NavitSpeech=(*jnienv)->NewObject(jnienv, ret->NavitSpeechClass, cid, android_activity); + dbg(0,"result=%p\n",ret->NavitSpeech); if (!ret->NavitSpeech) return 0; - if (ret->NavitSpeech) - (*jnienv)->NewGlobalRef(jnienv, ret->NavitSpeech); + if (ret->NavitSpeech) + ret->NavitSpeech = (*jnienv)->NewGlobalRef(jnienv, ret->NavitSpeech); return 1; } diff --git a/navit/navit/vehicle/android/vehicle_android.c b/navit/navit/vehicle/android/vehicle_android.c index 15f93a8..758ea91 100644 --- a/navit/navit/vehicle/android/vehicle_android.c +++ b/navit/navit/vehicle/android/vehicle_android.c @@ -186,7 +186,7 @@ vehicle_android_init(struct vehicle_priv *ret) if (!ret->NavitVehicle) return 0; if (ret->NavitVehicle) - (*jnienv)->NewGlobalRef(jnienv, ret->NavitVehicle); + ret->NavitVehicle = (*jnienv)->NewGlobalRef(jnienv, ret->NavitVehicle); return 1; }