diff options
author | Thomas Martitz <kugel@rockbox.org> | 2012-03-22 20:35:57 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2012-03-22 20:44:52 +0100 |
commit | 58e097d4a6c64bf762a8c30e24f16cc62c574519 (patch) | |
tree | 16f8135f9ced2e8cd815ff68024b6ef3f237e388 | |
parent | b0df3233917c51049a380f04b909f061de828972 (diff) | |
download | rockbox-58e097d4a6c64bf762a8c30e24f16cc62c574519.tar.gz rockbox-58e097d4a6c64bf762a8c30e24f16cc62c574519.zip |
android: Add facility for java code to wait native code to be ready.
Especially when unzipping rockbox.zip, the native code can be initialized
a lot later than the java code. The java code needs to be prevented from
accessing rockbox structures (e.g. current_tick, event queues) before they're
ready.
This commit adds wait_rockbox_ready() and fixes dodgy behavior of starting
rockbox via widget play button, headset remote buttons or multimedia keys.
Also fixes wrong small list items before first redraw.
Change-Id: I1caf925e829a9c1c6bb6e0016d5c80574574c91e
-rw-r--r-- | firmware/target/hosted/android/button-android.c | 6 | ||||
-rw-r--r-- | firmware/target/hosted/android/lcd-android.c | 3 | ||||
-rw-r--r-- | firmware/target/hosted/android/system-android.c | 38 | ||||
-rw-r--r-- | firmware/target/hosted/android/system-target.h | 7 | ||||
-rw-r--r-- | firmware/target/hosted/android/telephony-android.c | 10 |
5 files changed, 62 insertions, 2 deletions
diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index 406d37d25b..ee8b32d704 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c | |||
@@ -81,6 +81,8 @@ Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jclass class, | |||
81 | button = dpad_to_button((int)keycode); | 81 | button = dpad_to_button((int)keycode); |
82 | if (button) | 82 | if (button) |
83 | { | 83 | { |
84 | /* ensure button_queue can be safely posted to */ | ||
85 | wait_rockbox_ready(); | ||
84 | reset_poweroff_timer(); | 86 | reset_poweroff_timer(); |
85 | queue_post(&button_queue, button, 0); | 87 | queue_post(&button_queue, button, 0); |
86 | return true; | 88 | return true; |
@@ -121,6 +123,10 @@ void button_init_device(void) | |||
121 | e->NewObject(env_ptr, class, | 123 | e->NewObject(env_ptr, class, |
122 | constructor, | 124 | constructor, |
123 | RockboxService_instance); | 125 | RockboxService_instance); |
126 | /* when reaching this point, rockbox can be considered ready because the | ||
127 | * input system (button.c) is initialized. This implies the kernel and threading | ||
128 | * is up and running */ | ||
129 | set_rockbox_ready(); | ||
124 | } | 130 | } |
125 | 131 | ||
126 | int button_read_device(int *data) | 132 | int button_read_device(int *data) |
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index 4e4ea66268..15c844bbd6 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c | |||
@@ -122,6 +122,9 @@ Java_org_rockbox_RockboxFramebuffer_surfaceCreated(JNIEnv *env, jobject this, | |||
122 | connect_with_java(env, this); | 122 | connect_with_java(env, this); |
123 | display_on = true; | 123 | display_on = true; |
124 | 124 | ||
125 | /* need to wait for button_queue to be valid to post to */ | ||
126 | wait_rockbox_ready(); | ||
127 | |||
125 | send_event(LCD_EVENT_ACTIVATION, NULL); | 128 | send_event(LCD_EVENT_ACTIVATION, NULL); |
126 | /* Force an update, since the newly created surface is initially black | 129 | /* Force an update, since the newly created surface is initially black |
127 | * waiting for the next normal update results in a longish black screen */ | 130 | * waiting for the next normal update results in a longish black screen */ |
diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c index b3c4cdccb5..614d89bfd1 100644 --- a/firmware/target/hosted/android/system-android.c +++ b/firmware/target/hosted/android/system-android.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <setjmp.h> | 23 | #include <setjmp.h> |
24 | #include <jni.h> | 24 | #include <jni.h> |
25 | #include <pthread.h> | ||
25 | #include "config.h" | 26 | #include "config.h" |
26 | #include "system.h" | 27 | #include "system.h" |
27 | 28 | ||
@@ -95,3 +96,40 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this) | |||
95 | /* simply return here. this will allow the VM to clean up objects and do | 96 | /* simply return here. this will allow the VM to clean up objects and do |
96 | * garbage collection */ | 97 | * garbage collection */ |
97 | } | 98 | } |
99 | |||
100 | |||
101 | /* below is the facility for external (from other java threads) to safely call | ||
102 | * into our snative code. When extracting rockbox.zip the main function is | ||
103 | * called only after extraction. This delay can be accounted for by calling | ||
104 | * wait_rockbox_ready(). This does not return until the critical parts of Rockbox | ||
105 | * can be considered up and running. */ | ||
106 | static pthread_cond_t btn_cond = PTHREAD_COND_INITIALIZER; | ||
107 | static pthread_mutex_t btn_mtx = PTHREAD_MUTEX_INITIALIZER; | ||
108 | static bool initialized; | ||
109 | |||
110 | bool is_rockbox_ready(void) | ||
111 | { | ||
112 | /* don't bother with mutexes for this */ | ||
113 | return initialized; | ||
114 | } | ||
115 | |||
116 | void wait_rockbox_ready(void) | ||
117 | { | ||
118 | pthread_mutex_lock(&btn_mtx); | ||
119 | |||
120 | if (!initialized) | ||
121 | pthread_cond_wait(&btn_cond, &btn_mtx); | ||
122 | |||
123 | pthread_mutex_unlock(&btn_mtx); | ||
124 | } | ||
125 | |||
126 | void set_rockbox_ready(void) | ||
127 | { | ||
128 | pthread_mutex_lock(&btn_mtx); | ||
129 | |||
130 | initialized = true; | ||
131 | /* now ready. signal all waiters */ | ||
132 | pthread_cond_broadcast(&btn_cond); | ||
133 | |||
134 | pthread_mutex_unlock(&btn_mtx); | ||
135 | } | ||
diff --git a/firmware/target/hosted/android/system-target.h b/firmware/target/hosted/android/system-target.h index fd81b6661e..455fcc95fa 100644 --- a/firmware/target/hosted/android/system-target.h +++ b/firmware/target/hosted/android/system-target.h | |||
@@ -37,4 +37,11 @@ extern JNIEnv* getJavaEnvironment(void); | |||
37 | 37 | ||
38 | #endif /* __SYSTEM_TARGET_H__ */ | 38 | #endif /* __SYSTEM_TARGET_H__ */ |
39 | 39 | ||
40 | /* facility function to check/wait for rockbox being ready, to be used | ||
41 | * by java calls into native that depend on Rockbox structures such as | ||
42 | * initialized kernel. */ | ||
43 | bool is_rockbox_ready(void); | ||
44 | void wait_rockbox_ready(void); | ||
45 | void set_rockbox_ready(void); | ||
46 | |||
40 | #define NEED_GENERIC_BYTESWAPS | 47 | #define NEED_GENERIC_BYTESWAPS |
diff --git a/firmware/target/hosted/android/telephony-android.c b/firmware/target/hosted/android/telephony-android.c index df89a56e14..63f0f05e39 100644 --- a/firmware/target/hosted/android/telephony-android.c +++ b/firmware/target/hosted/android/telephony-android.c | |||
@@ -21,11 +21,15 @@ | |||
21 | 21 | ||
22 | 22 | ||
23 | #include <jni.h> | 23 | #include <jni.h> |
24 | #include "system.h" | ||
24 | #include "kernel.h" | 25 | #include "kernel.h" |
25 | 26 | ||
26 | extern JNIEnv *env_ptr; | 27 | extern JNIEnv *env_ptr; |
27 | extern jobject RockboxService_instance; | 28 | extern jobject RockboxService_instance; |
28 | 29 | ||
30 | /* telephony_init_device() is currently called in system_init(). Thus, there is | ||
31 | * a small chance of the callbacks (and queue_broadcast) being called before | ||
32 | * the kernel is initialized (this happens after system_init(). */ | ||
29 | 33 | ||
30 | void telephony_init_device(void) | 34 | void telephony_init_device(void) |
31 | { | 35 | { |
@@ -44,7 +48,8 @@ Java_org_rockbox_monitors_TelephonyMonitor_postCallIncoming(JNIEnv *env, jobject | |||
44 | { | 48 | { |
45 | (void)env; | 49 | (void)env; |
46 | (void)this; | 50 | (void)this; |
47 | queue_broadcast(SYS_CALL_INCOMING, 0); | 51 | if (is_rockbox_ready()) |
52 | queue_broadcast(SYS_CALL_INCOMING, 0); | ||
48 | } | 53 | } |
49 | 54 | ||
50 | JNIEXPORT void JNICALL | 55 | JNIEXPORT void JNICALL |
@@ -52,5 +57,6 @@ Java_org_rockbox_monitors_TelephonyMonitor_postCallHungUp(JNIEnv *env, jobject t | |||
52 | { | 57 | { |
53 | (void)env; | 58 | (void)env; |
54 | (void)this; | 59 | (void)this; |
55 | queue_broadcast(SYS_CALL_HUNG_UP, 0); | 60 | if (is_rockbox_ready()) |
61 | queue_broadcast(SYS_CALL_HUNG_UP, 0); | ||
56 | } | 62 | } |