summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-07 21:30:22 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-07 21:30:22 +0000
commitca4439ff65bdc93fc44f4cc1be52aab50217ce78 (patch)
tree06578c5243a9c7b0c4c5dcb322ffb9a4609b5e7a
parentf1184f963aea4cb16a5886c71cc662a0503e1cd5 (diff)
downloadrockbox-ca4439ff65bdc93fc44f4cc1be52aab50217ce78.tar.gz
rockbox-ca4439ff65bdc93fc44f4cc1be52aab50217ce78.zip
Android port: handle incoming calls.
Stop explicitely if a call comes in, and resume playback (if it was playing before the call) upon hang up. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27746 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--android/src/org/rockbox/RockboxTimer.java28
-rw-r--r--apps/menu.c13
-rw-r--r--apps/misc.c19
-rw-r--r--firmware/export/kernel.h2
-rw-r--r--firmware/target/hosted/android/kernel-android.c24
5 files changed, 79 insertions, 7 deletions
diff --git a/android/src/org/rockbox/RockboxTimer.java b/android/src/org/rockbox/RockboxTimer.java
index 6491e4ffe9..68a0e866fb 100644
--- a/android/src/org/rockbox/RockboxTimer.java
+++ b/android/src/org/rockbox/RockboxTimer.java
@@ -24,6 +24,8 @@ package org.rockbox;
24import java.util.Timer; 24import java.util.Timer;
25import java.util.TimerTask; 25import java.util.TimerTask;
26 26
27import android.content.Context;
28import android.telephony.TelephonyManager;
27import android.util.Log; 29import android.util.Log;
28 30
29public class RockboxTimer extends Timer 31public class RockboxTimer extends Timer
@@ -33,24 +35,42 @@ public class RockboxTimer extends Timer
33 35
34 private class RockboxTimerTask extends TimerTask { 36 private class RockboxTimerTask extends TimerTask {
35 private RockboxTimer t; 37 private RockboxTimer t;
36 public RockboxTimerTask(RockboxTimer parent) { 38 private TelephonyManager tm;
39 private int last_state;
40 public RockboxTimerTask(RockboxService s, RockboxTimer parent) {
37 super(); 41 super();
38 t = parent; 42 t = parent;
43 tm = (TelephonyManager)s.getSystemService(Context.TELEPHONY_SERVICE);
44 last_state = tm.getCallState();
39 } 45 }
40 46
41 @Override 47 @Override
42 public void run() { 48 public void run() {
43 timerTask(); 49 timerTask();
50 int state = tm.getCallState();
51 if (state != last_state)
52 {
53 switch (state) {
54 case TelephonyManager.CALL_STATE_IDLE:
55 postCallHungUp();
56 break;
57 case TelephonyManager.CALL_STATE_RINGING:
58 postCallIncoming();
59 default:
60 break;
61 }
62 last_state = state;
63 }
44 synchronized(t) { 64 synchronized(t) {
45 t.notify(); 65 t.notify();
46 } 66 }
47 } 67 }
48 } 68 }
49 69
50 public RockboxTimer(long period_inverval_in_ms) 70 public RockboxTimer(RockboxService instance, long period_inverval_in_ms)
51 { 71 {
52 super("tick timer", false); 72 super("tick timer", false);
53 task = new RockboxTimerTask(this); 73 task = new RockboxTimerTask(instance, this);
54 schedule(task, 0, period_inverval_in_ms); 74 schedule(task, 0, period_inverval_in_ms);
55 interval = period_inverval_in_ms; 75 interval = period_inverval_in_ms;
56 } 76 }
@@ -75,4 +95,6 @@ public class RockboxTimer extends Timer
75 } 95 }
76 } 96 }
77 public native void timerTask(); 97 public native void timerTask();
98 private native void postCallIncoming();
99 private native void postCallHungUp();
78} 100}
diff --git a/apps/menu.c b/apps/menu.c
index a88d725774..e6afec2d14 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -341,6 +341,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
341 const struct menu_item_ex *temp, *menu; 341 const struct menu_item_ex *temp, *menu;
342 int ret = 0, i; 342 int ret = 0, i;
343 bool redraw_lists; 343 bool redraw_lists;
344 int old_audio_status = audio_status();
344 FOR_NB_SCREENS(i) 345 FOR_NB_SCREENS(i)
345 viewportmanager_theme_enable(i, !hide_theme, NULL); 346 viewportmanager_theme_enable(i, !hide_theme, NULL);
346 347
@@ -380,6 +381,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
380#endif 381#endif
381 while (!done) 382 while (!done)
382 { 383 {
384 int new_old_audio_statusus;
383 redraw_lists = false; 385 redraw_lists = false;
384 if (!hide_theme) 386 if (!hide_theme)
385 { 387 {
@@ -389,6 +391,15 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
389 } 391 }
390 action = get_action(CONTEXT_MAINMENU, 392 action = get_action(CONTEXT_MAINMENU,
391 list_do_action_timeout(&lists, HZ)); 393 list_do_action_timeout(&lists, HZ));
394
395 /* query audio status to see if it changed */
396 new_old_audio_statusus = audio_status();
397 if (old_audio_status != new_old_audio_statusus)
398 { /* force a redraw if anything changed the audio status
399 * from outside */
400 redraw_lists = true;
401 old_audio_status = new_old_audio_statusus;
402 }
392 /* HZ so the status bar redraws corectly */ 403 /* HZ so the status bar redraws corectly */
393 404
394 if (menu_callback) 405 if (menu_callback)
@@ -410,8 +421,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
410 421
411 if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD)) 422 if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
412 continue; 423 continue;
413 if (action == ACTION_NONE)
414 continue;
415#ifdef HAVE_QUICKSCREEN 424#ifdef HAVE_QUICKSCREEN
416 else if (action == ACTION_STD_QUICKSCREEN) 425 else if (action == ACTION_STD_QUICKSCREEN)
417 { 426 {
diff --git a/apps/misc.c b/apps/misc.c
index ed6986180a..9fbdd433ef 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -517,6 +517,9 @@ static void unplug_change(bool inserted)
517 517
518long default_event_handler_ex(long event, void (*callback)(void *), void *parameter) 518long default_event_handler_ex(long event, void (*callback)(void *), void *parameter)
519{ 519{
520#if CONFIG_PLATFORM & PLATFORM_ANDROID
521 static bool resume = false;
522#endif
520 switch(event) 523 switch(event)
521 { 524 {
522 case SYS_BATTERY_UPDATE: 525 case SYS_BATTERY_UPDATE:
@@ -606,6 +609,22 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
606 iap_handlepkt(); 609 iap_handlepkt();
607 return SYS_IAP_HANDLEPKT; 610 return SYS_IAP_HANDLEPKT;
608#endif 611#endif
612#if CONFIG_PLATFORM & PLATFORM_ANDROID
613 /* stop playback if we receive a call */
614 case SYS_CALL_INCOMING:
615 resume = (audio_status() & AUDIO_STATUS_PLAY) != 0;
616 list_stop_handler();
617 return SYS_CALL_INCOMING;
618 /* resume playback if needed */
619 case SYS_CALL_HUNG_UP:
620 if (resume && playlist_resume() != -1)
621 {
622 playlist_start(global_status.resume_index,
623 global_status.resume_offset);
624 }
625 resume = false;
626 return SYS_CALL_HUNG_UP;
627#endif
609 } 628 }
610 return 0; 629 return 0;
611} 630}
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 9ef5af8c0c..d256f31ab5 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -82,6 +82,8 @@
82#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) 82#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0)
83#define SYS_IAP_PERIODIC MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1) 83#define SYS_IAP_PERIODIC MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 1)
84#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2) 84#define SYS_IAP_HANDLEPKT MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 2)
85#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
86#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
85 87
86#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) 88#define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT)
87 89
diff --git a/firmware/target/hosted/android/kernel-android.c b/firmware/target/hosted/android/kernel-android.c
index 1a9b97b419..636c849c24 100644
--- a/firmware/target/hosted/android/kernel-android.c
+++ b/firmware/target/hosted/android/kernel-android.c
@@ -23,14 +23,17 @@
23#include <jni.h> 23#include <jni.h>
24#include "config.h" 24#include "config.h"
25#include "system.h" 25#include "system.h"
26#include "button.h"
27#include "audio.h"
26 28
27extern JNIEnv *env_ptr; 29extern JNIEnv *env_ptr;
28 30
31extern jobject RockboxService_instance;
32
29static jclass RockboxTimer_class; 33static jclass RockboxTimer_class;
30static jobject RockboxTimer_instance; 34static jobject RockboxTimer_instance;
31static jmethodID java_wait_for_interrupt; 35static jmethodID java_wait_for_interrupt;
32static bool initialized = false; 36static bool initialized = false;
33
34/* 37/*
35 * This is called from the separate Timer java thread. I have not added any 38 * This is called from the separate Timer java thread. I have not added any
36 * interrupt simulation to it (like the sdl counterpart does), 39 * interrupt simulation to it (like the sdl counterpart does),
@@ -49,6 +52,22 @@ Java_org_rockbox_RockboxTimer_timerTask(JNIEnv *env, jobject this)
49 call_tick_tasks(); 52 call_tick_tasks();
50} 53}
51 54
55JNIEXPORT void JNICALL
56Java_org_rockbox_RockboxTimer_postCallIncoming(JNIEnv *env, jobject this)
57{
58 (void)env;
59 (void)this;
60 queue_broadcast(SYS_CALL_INCOMING, 0);
61}
62
63JNIEXPORT void JNICALL
64Java_org_rockbox_RockboxTimer_postCallHungUp(JNIEnv *env, jobject this)
65{
66 (void)env;
67 (void)this;
68 queue_broadcast(SYS_CALL_HUNG_UP, 0);
69}
70
52void tick_start(unsigned int interval_in_ms) 71void tick_start(unsigned int interval_in_ms)
53{ 72{
54 JNIEnv e = *env_ptr; 73 JNIEnv e = *env_ptr;
@@ -57,11 +76,12 @@ void tick_start(unsigned int interval_in_ms)
57 jmethodID constructor = e->GetMethodID(env_ptr, 76 jmethodID constructor = e->GetMethodID(env_ptr,
58 RockboxTimer_class, 77 RockboxTimer_class,
59 "<init>", 78 "<init>",
60 "(J)V"); 79 "(Lorg/rockbox/RockboxService;J)V");
61 /* the constructor will do the tick_start */ 80 /* the constructor will do the tick_start */
62 RockboxTimer_instance = e->NewObject(env_ptr, 81 RockboxTimer_instance = e->NewObject(env_ptr,
63 RockboxTimer_class, 82 RockboxTimer_class,
64 constructor, 83 constructor,
84 RockboxService_instance,
65 (jlong)interval_in_ms); 85 (jlong)interval_in_ms);
66 86
67 /* get our wfi func also */ 87 /* get our wfi func also */