diff --git a/android/src/org/rockbox/monitors/HeadphoneMonitor.java b/android/src/org/rockbox/monitors/HeadphoneMonitor.java index 99d2f7ab8a..72a2f262f2 100644 --- a/android/src/org/rockbox/monitors/HeadphoneMonitor.java +++ b/android/src/org/rockbox/monitors/HeadphoneMonitor.java @@ -29,7 +29,6 @@ import android.content.IntentFilter; public class HeadphoneMonitor extends BroadcastReceiver { @SuppressWarnings("unused") - private int mHpState; /* read by native code */ public HeadphoneMonitor(Context c) { @@ -45,7 +44,7 @@ public class HeadphoneMonitor extends BroadcastReceiver public void onReceive(Context arg0, Intent intent) { int state = intent.getIntExtra("state", -1); - mHpState = state; + postHpStateChanged(state); } /* audio becoming noise acts as headphones extracted */ @@ -54,7 +53,9 @@ public class HeadphoneMonitor extends BroadcastReceiver @Override public void onReceive(Context arg0, Intent arg1) { - mHpState = 0; + postHpStateChanged(0); } } + + private synchronized native void postHpStateChanged(int state); } diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index c913a3d7f7..6751effd1b 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c @@ -34,8 +34,6 @@ extern JNIEnv *env_ptr; extern jclass RockboxService_class; extern jobject RockboxService_instance; -static jobject HeadphoneMonitor_instance; -static jfieldID headphone_state; static int last_y, last_x; static int last_btns; @@ -120,13 +118,9 @@ void button_init_device(void) jmethodID constructor = e->GetMethodID(env_ptr, class, "", "(Landroid/content/Context;)V"); - HeadphoneMonitor_instance = e->NewObject(env_ptr, class, - constructor, - RockboxService_instance); - /* cache the battery level field id */ - headphone_state = (*env_ptr)->GetFieldID(env_ptr, - class, - "mHpState", "I"); + e->NewObject(env_ptr, class, + constructor, + RockboxService_instance); } int button_read_device(int *data) @@ -145,13 +139,23 @@ int button_read_device(int *data) return btn; } - -/* Tell if anything is in the jack. */ +static int hp_state; +JNIEXPORT void JNICALL +Java_org_rockbox_monitors_HeadphoneMonitor_postCallHungUp(JNIEnv *env, + jobject this, + jint state) +{ + (void)env; (void)this; + hp_state = state; +} +/* Tell if anything is in the jack. + * + * since this is called from the tick task, which isn't attached to + * the dalvik VM, it's not permitted to make JNI calls (therefore + * we need the above callback) */ bool headphones_inserted(void) { - int state = (*env_ptr)->GetIntField(env_ptr, HeadphoneMonitor_instance, - headphone_state); /* 0 is disconnected, 1 and 2 are connected */ - return (state == 0) ? false : true; + return (hp_state == 0) ? false : true; } diff --git a/firmware/target/hosted/android/kernel-android.c b/firmware/target/hosted/android/kernel-android.c index 80ff88fd12..e3522418fe 100644 --- a/firmware/target/hosted/android/kernel-android.c +++ b/firmware/target/hosted/android/kernel-android.c @@ -60,7 +60,13 @@ void interrupt(void) } /* - * setup a hrtimer to send a signal to our process every tick */ + * setup a hrtimer to send a signal to our process every tick + * + * WARNING: JNI calls are not permitted from tick tasks, as the + * underlying thread is not attached to the Java VM + * + * Can be possibly be attached if it really needs to be. but let's + * keep this leightweight */ void tick_start(unsigned int interval_in_ms) { int ret = 0;