summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-07-19 23:44:56 +0000
committerThomas Martitz <kugel@rockbox.org>2011-07-19 23:44:56 +0000
commitb2f52477dfce620c11e1707e69d3a5f8cab5f6d7 (patch)
tree094d7a9ce51c684ebec417cdcd954f379b49dfa7
parentb8bfa84d1bf74fcb133d7f5bbf49c39d38d9ed7d (diff)
downloadrockbox-b2f52477dfce620c11e1707e69d3a5f8cab5f6d7.tar.gz
rockbox-b2f52477dfce620c11e1707e69d3a5f8cab5f6d7.zip
Android: Change headphone detection to call into native.
Making a JNI call from tick tasks is not permitted as the underlying thread is not attached to the Java VM. This is an error and crashes in the emulator (which has stricter JNI checks enabled by default). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30173 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--android/src/org/rockbox/monitors/HeadphoneMonitor.java7
-rw-r--r--firmware/target/hosted/android/button-android.c32
-rw-r--r--firmware/target/hosted/android/kernel-android.c8
3 files changed, 29 insertions, 18 deletions
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;
29public class HeadphoneMonitor extends BroadcastReceiver 29public class HeadphoneMonitor extends BroadcastReceiver
30{ 30{
31 @SuppressWarnings("unused") 31 @SuppressWarnings("unused")
32 private int mHpState; /* read by native code */
33 32
34 public HeadphoneMonitor(Context c) 33 public HeadphoneMonitor(Context c)
35 { 34 {
@@ -45,7 +44,7 @@ public class HeadphoneMonitor extends BroadcastReceiver
45 public void onReceive(Context arg0, Intent intent) 44 public void onReceive(Context arg0, Intent intent)
46 { 45 {
47 int state = intent.getIntExtra("state", -1); 46 int state = intent.getIntExtra("state", -1);
48 mHpState = state; 47 postHpStateChanged(state);
49 } 48 }
50 49
51 /* audio becoming noise acts as headphones extracted */ 50 /* audio becoming noise acts as headphones extracted */
@@ -54,7 +53,9 @@ public class HeadphoneMonitor extends BroadcastReceiver
54 @Override 53 @Override
55 public void onReceive(Context arg0, Intent arg1) 54 public void onReceive(Context arg0, Intent arg1)
56 { 55 {
57 mHpState = 0; 56 postHpStateChanged(0);
58 } 57 }
59 } 58 }
59
60 private synchronized native void postHpStateChanged(int state);
60} 61}
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;
34extern jclass RockboxService_class; 34extern jclass RockboxService_class;
35extern jobject RockboxService_instance; 35extern jobject RockboxService_instance;
36 36
37static jobject HeadphoneMonitor_instance;
38static jfieldID headphone_state;
39static int last_y, last_x; 37static int last_y, last_x;
40static int last_btns; 38static int last_btns;
41 39
@@ -120,13 +118,9 @@ void button_init_device(void)
120 jmethodID constructor = e->GetMethodID(env_ptr, class, 118 jmethodID constructor = e->GetMethodID(env_ptr, class,
121 "<init>", 119 "<init>",
122 "(Landroid/content/Context;)V"); 120 "(Landroid/content/Context;)V");
123 HeadphoneMonitor_instance = e->NewObject(env_ptr, class, 121 e->NewObject(env_ptr, class,
124 constructor, 122 constructor,
125 RockboxService_instance); 123 RockboxService_instance);
126 /* cache the battery level field id */
127 headphone_state = (*env_ptr)->GetFieldID(env_ptr,
128 class,
129 "mHpState", "I");
130} 124}
131 125
132int button_read_device(int *data) 126int button_read_device(int *data)
@@ -145,13 +139,23 @@ int button_read_device(int *data)
145 return btn; 139 return btn;
146} 140}
147 141
148 142static int hp_state;
149/* Tell if anything is in the jack. */ 143JNIEXPORT void JNICALL
144Java_org_rockbox_monitors_HeadphoneMonitor_postCallHungUp(JNIEnv *env,
145 jobject this,
146 jint state)
147{
148 (void)env; (void)this;
149 hp_state = state;
150}
151/* Tell if anything is in the jack.
152 *
153 * since this is called from the tick task, which isn't attached to
154 * the dalvik VM, it's not permitted to make JNI calls (therefore
155 * we need the above callback) */
150bool headphones_inserted(void) 156bool headphones_inserted(void)
151{ 157{
152 int state = (*env_ptr)->GetIntField(env_ptr, HeadphoneMonitor_instance,
153 headphone_state);
154 /* 0 is disconnected, 1 and 2 are connected */ 158 /* 0 is disconnected, 1 and 2 are connected */
155 return (state == 0) ? false : true; 159 return (hp_state == 0) ? false : true;
156} 160}
157 161
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)
60} 60}
61 61
62/* 62/*
63 * setup a hrtimer to send a signal to our process every tick */ 63 * setup a hrtimer to send a signal to our process every tick
64 *
65 * WARNING: JNI calls are not permitted from tick tasks, as the
66 * underlying thread is not attached to the Java VM
67 *
68 * Can be possibly be attached if it really needs to be. but let's
69 * keep this leightweight */
64void tick_start(unsigned int interval_in_ms) 70void tick_start(unsigned int interval_in_ms)
65{ 71{
66 int ret = 0; 72 int ret = 0;