summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-03-16 15:17:24 +0000
committerThomas Martitz <kugel@rockbox.org>2011-03-16 15:17:24 +0000
commit8c46ddf9d719fb29f483dc21993167907953f39c (patch)
tree03d99235b88ba6f327db503f65e67061ae5568e3
parent046cec3aa7fd58a9519cad8d693b47a2400e1742 (diff)
downloadrockbox-8c46ddf9d719fb29f483dc21993167907953f39c.tar.gz
rockbox-8c46ddf9d719fb29f483dc21993167907953f39c.tar.bz2
rockbox-8c46ddf9d719fb29f483dc21993167907953f39c.zip
Android: Implement app shutdown and thus, sleep timer.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29602 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--android/src/org/rockbox/RockboxActivity.java3
-rw-r--r--android/src/org/rockbox/RockboxService.java14
-rw-r--r--apps/misc.c7
-rw-r--r--firmware/target/hosted/android/pcm-android.c12
-rw-r--r--firmware/target/hosted/android/system-android.c26
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, "<init>", "()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 <setjmp.h>
#include <jni.h>
#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 */
}