From 8c46ddf9d719fb29f483dc21993167907953f39c Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Wed, 16 Mar 2011 15:17:24 +0000 Subject: Android: Implement app shutdown and thus, sleep timer. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29602 a1c6a512-1295-4272-9138-f99709370657 --- android/src/org/rockbox/RockboxActivity.java | 3 +++ android/src/org/rockbox/RockboxService.java | 14 ++++++++++++- apps/misc.c | 7 ------- firmware/target/hosted/android/pcm-android.c | 12 +++++++++++- firmware/target/hosted/android/system-android.c | 26 ++++++++++++++++++++----- 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java index 2e601cf041..cae0510229 100644 --- a/android/src/org/rockbox/RockboxActivity.java +++ b/android/src/org/rockbox/RockboxActivity.java @@ -81,6 +81,9 @@ public class RockboxActivity extends Activity case RockboxService.RESULT_ERROR_OCCURED: Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG); break; + case RockboxService.RESULT_ROCKBOX_EXIT: + finish(); + break; } } }); diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index 3d7d7908c0..d078fe83b6 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java @@ -75,6 +75,7 @@ public class RockboxService extends Service public static final int RESULT_SERVICE_RUNNING = 3; public static final int RESULT_ERROR_OCCURED = 4; public static final int RESULT_LIB_LOADED = 5; + public static final int RESULT_ROCKBOX_EXIT = 6; @Override public void onCreate() @@ -270,7 +271,12 @@ public class RockboxService extends Service resultReceiver.send(RESULT_INVOKING_MAIN, null); main(); - throw new IllegalStateException("native main() returned!"); + + if (resultReceiver != null) + resultReceiver.send(RESULT_ROCKBOX_EXIT, null); + + LOG("Stop service: main() returned"); + stopSelf(); /* serivce is of no use anymore */ } }, "Rockbox thread"); rb.setDaemon(false); @@ -353,5 +359,11 @@ public class RockboxService extends Service stopForeground(); instance = null; rockbox_running = false; + System.runFinalization(); + /* exit() seems unclean but is needed in order to get the .so file garbage + * collected, otherwise Android caches this Service and librockbox.so + * The library must be reloaded to zero the bss and reset data + * segment */ + System.exit(0); } } diff --git a/apps/misc.c b/apps/misc.c index 995d65644e..0d25e2aa96 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -257,12 +257,6 @@ static void system_restore(void) static bool clean_shutdown(void (*callback)(void *), void *parameter) { -#if (CONFIG_PLATFORM & PLATFORM_ANDROID) - (void)callback; - (void)parameter; - bookmark_autobookmark(false); - call_storage_idle_notifys(true); -#else long msg_id = -1; int i; @@ -373,7 +367,6 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) shutdown_hw(); } -#endif return false; } diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c index edb3503262..cc8bd9c48a 100644 --- a/firmware/target/hosted/android/pcm-android.c +++ b/firmware/target/hosted/android/pcm-android.c @@ -36,6 +36,7 @@ static char *pcm_data_start; static jmethodID play_pause_method; static jmethodID stop_method; static jmethodID set_volume_method; +static jclass RockboxPCM_class; static jobject RockboxPCM_instance; @@ -159,7 +160,7 @@ void pcm_play_dma_init(void) **/ JNIEnv e = *env_ptr; /* get the class and its constructor */ - jclass RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); + RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "", "()V"); /* instance = new RockboxPCM() */ RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor); @@ -180,6 +181,15 @@ void pcm_set_mixer_volume(int volume) (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); } +/* + * release audio resources */ +void pcm_shutdown(void) +{ + JNIEnv e = *env_ptr; + jmethodID release = e->GetMethodID(env_ptr, RockboxPCM_class, "release", "()V"); + e->CallVoidMethod(env_ptr, RockboxPCM_instance, release); +} + /* Due to limitations of default_event_handler(), parameters gets swallowed when * being posted with queue_broadcast(), so workaround this by caching the last * value. diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c index 686453cfbb..fba7ff4e2c 100644 --- a/firmware/target/hosted/android/system-android.c +++ b/firmware/target/hosted/android/system-android.c @@ -20,6 +20,7 @@ ****************************************************************************/ +#include #include #include "config.h" #include "system.h" @@ -37,10 +38,17 @@ uintptr_t *stackend; extern int main(void); extern void telephony_init_device(void); +extern void pcm_shutdown(void); void system_exception_wait(void) { } void system_reboot(void) { } -void power_off(void) { } + +/* this is used to return from the entry point of the native library. */ +static jmp_buf poweroff_buf; +void shutdown_hw(void) +{ + longjmp(poweroff_buf, 1); +} void system_init(void) { @@ -75,10 +83,18 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this) volatile uintptr_t stack = 0; stackbegin = stackend = (uintptr_t*) &stack; - env_ptr = env; + /* setup a jmp_buf to come back later in case of exit */ + if (setjmp(poweroff_buf) == 0) + { + env_ptr = env; + + RockboxService_instance = this; + RockboxService_class = (*env)->GetObjectClass(env, this); - RockboxService_instance = this; - RockboxService_class = (*env)->GetObjectClass(env, this); + main(); + } - main(); + pcm_shutdown(); + /* simply return here. this will allow the VM to clean up objects and do + * garbage collection */ } -- cgit