diff options
-rw-r--r-- | android/src/org/rockbox/RockboxActivity.java | 3 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxService.java | 14 | ||||
-rw-r--r-- | apps/misc.c | 7 | ||||
-rw-r--r-- | firmware/target/hosted/android/pcm-android.c | 12 | ||||
-rw-r--r-- | 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 | |||
81 | case RockboxService.RESULT_ERROR_OCCURED: | 81 | case RockboxService.RESULT_ERROR_OCCURED: |
82 | Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG); | 82 | Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG); |
83 | break; | 83 | break; |
84 | case RockboxService.RESULT_ROCKBOX_EXIT: | ||
85 | finish(); | ||
86 | break; | ||
84 | } | 87 | } |
85 | } | 88 | } |
86 | }); | 89 | }); |
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 | |||
75 | public static final int RESULT_SERVICE_RUNNING = 3; | 75 | public static final int RESULT_SERVICE_RUNNING = 3; |
76 | public static final int RESULT_ERROR_OCCURED = 4; | 76 | public static final int RESULT_ERROR_OCCURED = 4; |
77 | public static final int RESULT_LIB_LOADED = 5; | 77 | public static final int RESULT_LIB_LOADED = 5; |
78 | public static final int RESULT_ROCKBOX_EXIT = 6; | ||
78 | 79 | ||
79 | @Override | 80 | @Override |
80 | public void onCreate() | 81 | public void onCreate() |
@@ -270,7 +271,12 @@ public class RockboxService extends Service | |||
270 | resultReceiver.send(RESULT_INVOKING_MAIN, null); | 271 | resultReceiver.send(RESULT_INVOKING_MAIN, null); |
271 | 272 | ||
272 | main(); | 273 | main(); |
273 | throw new IllegalStateException("native main() returned!"); | 274 | |
275 | if (resultReceiver != null) | ||
276 | resultReceiver.send(RESULT_ROCKBOX_EXIT, null); | ||
277 | |||
278 | LOG("Stop service: main() returned"); | ||
279 | stopSelf(); /* serivce is of no use anymore */ | ||
274 | } | 280 | } |
275 | }, "Rockbox thread"); | 281 | }, "Rockbox thread"); |
276 | rb.setDaemon(false); | 282 | rb.setDaemon(false); |
@@ -353,5 +359,11 @@ public class RockboxService extends Service | |||
353 | stopForeground(); | 359 | stopForeground(); |
354 | instance = null; | 360 | instance = null; |
355 | rockbox_running = false; | 361 | rockbox_running = false; |
362 | System.runFinalization(); | ||
363 | /* exit() seems unclean but is needed in order to get the .so file garbage | ||
364 | * collected, otherwise Android caches this Service and librockbox.so | ||
365 | * The library must be reloaded to zero the bss and reset data | ||
366 | * segment */ | ||
367 | System.exit(0); | ||
356 | } | 368 | } |
357 | } | 369 | } |
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) | |||
257 | 257 | ||
258 | static bool clean_shutdown(void (*callback)(void *), void *parameter) | 258 | static bool clean_shutdown(void (*callback)(void *), void *parameter) |
259 | { | 259 | { |
260 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) | ||
261 | (void)callback; | ||
262 | (void)parameter; | ||
263 | bookmark_autobookmark(false); | ||
264 | call_storage_idle_notifys(true); | ||
265 | #else | ||
266 | long msg_id = -1; | 260 | long msg_id = -1; |
267 | int i; | 261 | int i; |
268 | 262 | ||
@@ -373,7 +367,6 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) | |||
373 | 367 | ||
374 | shutdown_hw(); | 368 | shutdown_hw(); |
375 | } | 369 | } |
376 | #endif | ||
377 | return false; | 370 | return false; |
378 | } | 371 | } |
379 | 372 | ||
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; | |||
36 | static jmethodID play_pause_method; | 36 | static jmethodID play_pause_method; |
37 | static jmethodID stop_method; | 37 | static jmethodID stop_method; |
38 | static jmethodID set_volume_method; | 38 | static jmethodID set_volume_method; |
39 | static jclass RockboxPCM_class; | ||
39 | static jobject RockboxPCM_instance; | 40 | static jobject RockboxPCM_instance; |
40 | 41 | ||
41 | 42 | ||
@@ -159,7 +160,7 @@ void pcm_play_dma_init(void) | |||
159 | **/ | 160 | **/ |
160 | JNIEnv e = *env_ptr; | 161 | JNIEnv e = *env_ptr; |
161 | /* get the class and its constructor */ | 162 | /* get the class and its constructor */ |
162 | jclass RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); | 163 | RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); |
163 | jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "<init>", "()V"); | 164 | jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "<init>", "()V"); |
164 | /* instance = new RockboxPCM() */ | 165 | /* instance = new RockboxPCM() */ |
165 | RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor); | 166 | RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor); |
@@ -180,6 +181,15 @@ void pcm_set_mixer_volume(int volume) | |||
180 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); | 181 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); |
181 | } | 182 | } |
182 | 183 | ||
184 | /* | ||
185 | * release audio resources */ | ||
186 | void pcm_shutdown(void) | ||
187 | { | ||
188 | JNIEnv e = *env_ptr; | ||
189 | jmethodID release = e->GetMethodID(env_ptr, RockboxPCM_class, "release", "()V"); | ||
190 | e->CallVoidMethod(env_ptr, RockboxPCM_instance, release); | ||
191 | } | ||
192 | |||
183 | /* Due to limitations of default_event_handler(), parameters gets swallowed when | 193 | /* Due to limitations of default_event_handler(), parameters gets swallowed when |
184 | * being posted with queue_broadcast(), so workaround this by caching the last | 194 | * being posted with queue_broadcast(), so workaround this by caching the last |
185 | * value. | 195 | * 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 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | 22 | ||
23 | #include <setjmp.h> | ||
23 | #include <jni.h> | 24 | #include <jni.h> |
24 | #include "config.h" | 25 | #include "config.h" |
25 | #include "system.h" | 26 | #include "system.h" |
@@ -37,10 +38,17 @@ uintptr_t *stackend; | |||
37 | 38 | ||
38 | extern int main(void); | 39 | extern int main(void); |
39 | extern void telephony_init_device(void); | 40 | extern void telephony_init_device(void); |
41 | extern void pcm_shutdown(void); | ||
40 | 42 | ||
41 | void system_exception_wait(void) { } | 43 | void system_exception_wait(void) { } |
42 | void system_reboot(void) { } | 44 | void system_reboot(void) { } |
43 | void power_off(void) { } | 45 | |
46 | /* this is used to return from the entry point of the native library. */ | ||
47 | static jmp_buf poweroff_buf; | ||
48 | void shutdown_hw(void) | ||
49 | { | ||
50 | longjmp(poweroff_buf, 1); | ||
51 | } | ||
44 | 52 | ||
45 | void system_init(void) | 53 | void system_init(void) |
46 | { | 54 | { |
@@ -75,10 +83,18 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this) | |||
75 | 83 | ||
76 | volatile uintptr_t stack = 0; | 84 | volatile uintptr_t stack = 0; |
77 | stackbegin = stackend = (uintptr_t*) &stack; | 85 | stackbegin = stackend = (uintptr_t*) &stack; |
78 | env_ptr = env; | 86 | /* setup a jmp_buf to come back later in case of exit */ |
87 | if (setjmp(poweroff_buf) == 0) | ||
88 | { | ||
89 | env_ptr = env; | ||
90 | |||
91 | RockboxService_instance = this; | ||
92 | RockboxService_class = (*env)->GetObjectClass(env, this); | ||
79 | 93 | ||
80 | RockboxService_instance = this; | 94 | main(); |
81 | RockboxService_class = (*env)->GetObjectClass(env, this); | 95 | } |
82 | 96 | ||
83 | main(); | 97 | pcm_shutdown(); |
98 | /* simply return here. this will allow the VM to clean up objects and do | ||
99 | * garbage collection */ | ||
84 | } | 100 | } |