diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2011-06-04 19:17:47 +0000 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2011-06-04 19:17:47 +0000 |
commit | 6c22be4a3db4ad72acf67f99059872e92d1931b4 (patch) | |
tree | 110956169d637cdda501a2dfb3f9097d89d09ad8 | |
parent | 304312dc2fe17d9cdec2cc03a5883eade62e661b (diff) | |
download | rockbox-6c22be4a3db4ad72acf67f99059872e92d1931b4.tar.gz rockbox-6c22be4a3db4ad72acf67f99059872e92d1931b4.zip |
Android: implement headphone detection thus enabling pause on unplug (FS#12097).
Listen to headphone plug events. There are currently two glitches with this:
- Android takes a while until it reports the unplug event, so there will be
some delay until playback gets paused. This is an Android limitation.
- Rockbox debounces headphone state changes for one second. Therefore playback
will shortly be routed to the speaker on unplug until Rockbox does the actual
pause.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29956 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | android/src/org/rockbox/RockboxService.java | 21 | ||||
-rw-r--r-- | firmware/export/config/android.h | 2 | ||||
-rw-r--r-- | firmware/target/hosted/android/button-android.c | 28 |
3 files changed, 51 insertions, 0 deletions
diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index 346e4a189c..71b133edc8 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java | |||
@@ -64,10 +64,13 @@ public class RockboxService extends Service | |||
64 | private static volatile boolean rockbox_running; | 64 | private static volatile boolean rockbox_running; |
65 | private Activity current_activity = null; | 65 | private Activity current_activity = null; |
66 | private IntentFilter itf; | 66 | private IntentFilter itf; |
67 | private IntentFilter ifh; | ||
67 | private BroadcastReceiver batt_monitor; | 68 | private BroadcastReceiver batt_monitor; |
69 | private BroadcastReceiver headphone_monitor; | ||
68 | private RunForegroundManager fg_runner; | 70 | private RunForegroundManager fg_runner; |
69 | private MediaButtonReceiver mMediaButtonReceiver; | 71 | private MediaButtonReceiver mMediaButtonReceiver; |
70 | private int battery_level; | 72 | private int battery_level; |
73 | private int headphone_state; | ||
71 | private ResultReceiver resultReceiver; | 74 | private ResultReceiver resultReceiver; |
72 | 75 | ||
73 | public static final int RESULT_INVOKING_MAIN = 0; | 76 | public static final int RESULT_INVOKING_MAIN = 0; |
@@ -339,6 +342,24 @@ public class RockboxService extends Service | |||
339 | registerReceiver(batt_monitor, itf); | 342 | registerReceiver(batt_monitor, itf); |
340 | } | 343 | } |
341 | 344 | ||
345 | |||
346 | private void initHeadphoneMonitor() | ||
347 | { | ||
348 | ifh = new IntentFilter(Intent.ACTION_HEADSET_PLUG); | ||
349 | headphone_monitor = new BroadcastReceiver() | ||
350 | { | ||
351 | @Override | ||
352 | public void onReceive(Context context, Intent intent) | ||
353 | { | ||
354 | int state = intent.getIntExtra("state", -1); | ||
355 | LOG("headphone state:" + state); | ||
356 | headphone_state = state; | ||
357 | } | ||
358 | }; | ||
359 | registerReceiver(headphone_monitor, ifh); | ||
360 | } | ||
361 | |||
362 | |||
342 | void startForeground() | 363 | void startForeground() |
343 | { | 364 | { |
344 | fg_runner.startForeground(); | 365 | fg_runner.startForeground(); |
diff --git a/firmware/export/config/android.h b/firmware/export/config/android.h index 69a758d69b..41ecacfb9d 100644 --- a/firmware/export/config/android.h +++ b/firmware/export/config/android.h | |||
@@ -84,6 +84,8 @@ | |||
84 | 84 | ||
85 | #define HAVE_SW_TONE_CONTROLS | 85 | #define HAVE_SW_TONE_CONTROLS |
86 | 86 | ||
87 | #define HAVE_HEADPHONE_DETECTION | ||
88 | |||
87 | /* Define current usage levels. */ | 89 | /* Define current usage levels. */ |
88 | #define CURRENT_NORMAL 88 /* 18 hours from a 1600 mAh battery */ | 90 | #define CURRENT_NORMAL 88 /* 18 hours from a 1600 mAh battery */ |
89 | #define CURRENT_BACKLIGHT 30 /* TBD */ | 91 | #define CURRENT_BACKLIGHT 30 /* TBD */ |
diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index 61d7256a11..dfc5bd0fb3 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c | |||
@@ -31,6 +31,10 @@ | |||
31 | #include "powermgmt.h" | 31 | #include "powermgmt.h" |
32 | 32 | ||
33 | extern JNIEnv *env_ptr; | 33 | extern JNIEnv *env_ptr; |
34 | extern jclass RockboxService_class; | ||
35 | extern jobject RockboxService_instance; | ||
36 | |||
37 | static jfieldID _headphone_state; | ||
34 | static int last_y, last_x; | 38 | static int last_y, last_x; |
35 | static int last_btns; | 39 | static int last_btns; |
36 | 40 | ||
@@ -110,6 +114,20 @@ Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jclass class, | |||
110 | 114 | ||
111 | void button_init_device(void) | 115 | void button_init_device(void) |
112 | { | 116 | { |
117 | jmethodID initHeadphoneMonitor = (*env_ptr)->GetMethodID(env_ptr, | ||
118 | RockboxService_class, | ||
119 | "initHeadphoneMonitor", | ||
120 | "()V"); | ||
121 | /* start the monitor */ | ||
122 | (*env_ptr)->CallVoidMethod(env_ptr, | ||
123 | RockboxService_instance, | ||
124 | initHeadphoneMonitor); | ||
125 | |||
126 | /* cache the headphone state field id */ | ||
127 | _headphone_state = (*env_ptr)->GetFieldID(env_ptr, | ||
128 | RockboxService_class, | ||
129 | "headphone_state", | ||
130 | "I"); | ||
113 | } | 131 | } |
114 | 132 | ||
115 | int button_read_device(int *data) | 133 | int button_read_device(int *data) |
@@ -127,3 +145,13 @@ int button_read_device(int *data) | |||
127 | 145 | ||
128 | return btn; | 146 | return btn; |
129 | } | 147 | } |
148 | |||
149 | |||
150 | /* Tell if anything is in the jack. */ | ||
151 | bool headphones_inserted(void) | ||
152 | { | ||
153 | int state = (*env_ptr)->GetIntField(env_ptr, RockboxService_instance, _headphone_state); | ||
154 | /* 0 is disconnected, 1 and 2 are connected */ | ||
155 | return (state == 0) ? false : true; | ||
156 | } | ||
157 | |||