Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit 58e097d4a6c64bf762a8c30e24f16cc62c574519 1 parent b0df323
@kugel- authored
View
6 firmware/target/hosted/android/button-android.c
@@ -81,6 +81,8 @@ Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jclass class,
button = dpad_to_button((int)keycode);
if (button)
{
+ /* ensure button_queue can be safely posted to */
+ wait_rockbox_ready();
reset_poweroff_timer();
queue_post(&button_queue, button, 0);
return true;
@@ -121,6 +123,10 @@ void button_init_device(void)
e->NewObject(env_ptr, class,
constructor,
RockboxService_instance);
+ /* when reaching this point, rockbox can be considered ready because the
+ * input system (button.c) is initialized. This implies the kernel and threading
+ * is up and running */
+ set_rockbox_ready();
}
int button_read_device(int *data)
View
3  firmware/target/hosted/android/lcd-android.c
@@ -122,6 +122,9 @@ Java_org_rockbox_RockboxFramebuffer_surfaceCreated(JNIEnv *env, jobject this,
connect_with_java(env, this);
display_on = true;
+ /* need to wait for button_queue to be valid to post to */
+ wait_rockbox_ready();
+
send_event(LCD_EVENT_ACTIVATION, NULL);
/* Force an update, since the newly created surface is initially black
* waiting for the next normal update results in a longish black screen */
View
38 firmware/target/hosted/android/system-android.c
@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <jni.h>
+#include <pthread.h>
#include "config.h"
#include "system.h"
@@ -95,3 +96,40 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this)
/* simply return here. this will allow the VM to clean up objects and do
* garbage collection */
}
+
+
+/* below is the facility for external (from other java threads) to safely call
+ * into our snative code. When extracting rockbox.zip the main function is
+ * called only after extraction. This delay can be accounted for by calling
+ * wait_rockbox_ready(). This does not return until the critical parts of Rockbox
+ * can be considered up and running. */
+static pthread_cond_t btn_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t btn_mtx = PTHREAD_MUTEX_INITIALIZER;
+static bool initialized;
+
+bool is_rockbox_ready(void)
+{
+ /* don't bother with mutexes for this */
+ return initialized;
+}
+
+void wait_rockbox_ready(void)
+{
+ pthread_mutex_lock(&btn_mtx);
+
+ if (!initialized)
+ pthread_cond_wait(&btn_cond, &btn_mtx);
+
+ pthread_mutex_unlock(&btn_mtx);
+}
+
+void set_rockbox_ready(void)
+{
+ pthread_mutex_lock(&btn_mtx);
+
+ initialized = true;
+ /* now ready. signal all waiters */
+ pthread_cond_broadcast(&btn_cond);
+
+ pthread_mutex_unlock(&btn_mtx);
+}
View
7 firmware/target/hosted/android/system-target.h
@@ -37,4 +37,11 @@ extern JNIEnv* getJavaEnvironment(void);
#endif /* __SYSTEM_TARGET_H__ */
+/* facility function to check/wait for rockbox being ready, to be used
+ * by java calls into native that depend on Rockbox structures such as
+ * initialized kernel. */
+bool is_rockbox_ready(void);
+void wait_rockbox_ready(void);
+void set_rockbox_ready(void);
+
#define NEED_GENERIC_BYTESWAPS
View
10 firmware/target/hosted/android/telephony-android.c
@@ -21,11 +21,15 @@
#include <jni.h>
+#include "system.h"
#include "kernel.h"
extern JNIEnv *env_ptr;
extern jobject RockboxService_instance;
+/* telephony_init_device() is currently called in system_init(). Thus, there is
+ * a small chance of the callbacks (and queue_broadcast) being called before
+ * the kernel is initialized (this happens after system_init(). */
void telephony_init_device(void)
{
@@ -44,7 +48,8 @@ Java_org_rockbox_monitors_TelephonyMonitor_postCallIncoming(JNIEnv *env, jobject
{
(void)env;
(void)this;
- queue_broadcast(SYS_CALL_INCOMING, 0);
+ if (is_rockbox_ready())
+ queue_broadcast(SYS_CALL_INCOMING, 0);
}
JNIEXPORT void JNICALL
@@ -52,5 +57,6 @@ Java_org_rockbox_monitors_TelephonyMonitor_postCallHungUp(JNIEnv *env, jobject t
{
(void)env;
(void)this;
- queue_broadcast(SYS_CALL_HUNG_UP, 0);
+ if (is_rockbox_ready())
+ queue_broadcast(SYS_CALL_HUNG_UP, 0);
}
Please sign in to comment.
Something went wrong with that request. Please try again.