Android: Partly revert r29569 and only call the new getJavaEnvironment() when needed.

The environment is fine to share in general, just not across OS threads, so it's only needed
for functions which are possibly called from multiple OS threads (only 1 currently).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29601 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Thomas Martitz 2011-03-16 14:33:55 +00:00
parent efa9f13500
commit 046cec3aa7
10 changed files with 50 additions and 55 deletions

View file

@ -29,6 +29,7 @@
#include "system.h"
#include "touchscreen.h"
extern JNIEnv *env_ptr;
static int last_y, last_x;
static int last_btns;

View file

@ -28,6 +28,7 @@
#include "lcd.h"
#include "button.h"
extern JNIEnv *env_ptr;
extern jobject RockboxService_instance;
static jobject RockboxFramebuffer_instance;
@ -90,8 +91,6 @@ void lcd_init_device(void)
void lcd_update(void)
{
JNIEnv *env_ptr = getJavaEnvironment();
if (display_on)
(*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance,
java_lcd_update);
@ -99,8 +98,6 @@ void lcd_update(void)
void lcd_update_rect(int x, int y, int width, int height)
{
JNIEnv *env_ptr = getJavaEnvironment();
if (display_on)
(*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance,
java_lcd_update_rect, x, y, width, height);

View file

@ -21,10 +21,13 @@
#include <jni.h>
#include <stdbool.h>
#define _SYSTEM_WITH_JNI /* for getJavaEnvironment */
#include <system.h>
#include "debug.h"
#include "pcm.h"
extern JNIEnv *env_ptr;
/* infos about our pcm chunks */
static size_t pcm_data_size;
static char *pcm_data_start;
@ -115,17 +118,17 @@ void pcm_play_dma_start(const void *addr, size_t size)
void pcm_play_dma_stop(void)
{
JNIEnv *env_ptr = getJavaEnvironment();
(*env_ptr)->CallVoidMethod(env_ptr,
RockboxPCM_instance,
stop_method);
/* NOTE: due to how pcm_play_get_more_callback() works, this is
* possibly called from pcmSamplesToByteArray(), i.e. another thread.
* => We need to discover the env_ptr */
JNIEnv* env = getJavaEnvironment();
(*env)->CallVoidMethod(env,
RockboxPCM_instance,
stop_method);
}
void pcm_play_dma_pause(bool pause)
{
JNIEnv *env_ptr = getJavaEnvironment();
(*env_ptr)->CallVoidMethod(env_ptr,
RockboxPCM_instance,
play_pause_method,
@ -154,7 +157,6 @@ void pcm_play_dma_init(void)
* Luckily we only reference the PCM object from here, so it's safe (and
* clean) to allocate it here
**/
JNIEnv *env_ptr = getJavaEnvironment();
JNIEnv e = *env_ptr;
/* get the class and its constructor */
jclass RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM");
@ -175,8 +177,6 @@ void pcm_postinit(void)
void pcm_set_mixer_volume(int volume)
{
JNIEnv *env_ptr = getJavaEnvironment();
(*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume);
}

View file

@ -23,8 +23,8 @@
#include <jni.h>
#include <stdbool.h>
#include "config.h"
#include "system.h"
extern JNIEnv *env_ptr;
extern jclass RockboxService_class;
extern jobject RockboxService_instance;
@ -32,8 +32,6 @@ static jfieldID _battery_level;
void powermgmt_init_target(void)
{
JNIEnv *env_ptr = getJavaEnvironment();
jmethodID initBatteryMonitor = (*env_ptr)->GetMethodID(env_ptr,
RockboxService_class,
"initBatteryMonitor",
@ -52,8 +50,6 @@ void powermgmt_init_target(void)
int battery_level(void)
{
JNIEnv *env_ptr = getJavaEnvironment();
return (*env_ptr)->GetIntField(env_ptr, RockboxService_instance, _battery_level);
}

View file

@ -27,7 +27,8 @@
/* global fields for use with various JNI calls */
JavaVM *vm_ptr;
static JavaVM *vm_ptr;
JNIEnv *env_ptr;
jobject RockboxService_instance;
jclass RockboxService_class;
@ -47,6 +48,22 @@ void system_init(void)
telephony_init_device();
}
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void* reserved)
{
(void)reserved;
vm_ptr = vm;
return JNI_VERSION_1_2;
}
JNIEnv* getJavaEnvironment(void)
{
JNIEnv* env;
(*vm_ptr)->GetEnv(vm_ptr, (void**) &env, JNI_VERSION_1_2);
return env;
}
/* this is the entry point of the android app initially called by jni */
JNIEXPORT void JNICALL
Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this)
@ -58,8 +75,8 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this)
volatile uintptr_t stack = 0;
stackbegin = stackend = (uintptr_t*) &stack;
env_ptr = env;
(*env)->GetJavaVM(env, &vm_ptr);
RockboxService_instance = this;
RockboxService_class = (*env)->GetObjectClass(env, this);

View file

@ -21,8 +21,6 @@
#ifndef __SYSTEM_TARGET_H__
#define __SYSTEM_TARGET_H__
#include <jni.h>
#define disable_irq()
#define enable_irq()
#define disable_irq_save() 0
@ -32,19 +30,15 @@ void power_off(void);
void wait_for_interrupt(void);
void interrupt(void);
/* A JNI environment is specific to its thread, so use the correct way to
* obtain it: share a pointer to the JavaVM structure and ask that the JNI
* environment attached to the current thread. */
static inline JNIEnv* getJavaEnvironment(void)
{
extern JavaVM *vm_ptr;
JNIEnv *env = NULL;
if (vm_ptr)
(*vm_ptr)->GetEnv(vm_ptr, (void**) &env, JNI_VERSION_1_2);
return env;
}
/* don't pull in jni.h for every user of this file, it should be only needed
* within the target tree (if at all)
* define this before #including system.h or system-target.h */
#ifdef _SYSTEM_WITH_JNI
#include <jni.h>
/*
* discover the JNIEnv for this the calling thread in case it's not known */
extern JNIEnv* getJavaEnvironment(void);
#endif /* _SYSTEM_WITH_JNI */
#endif /* __SYSTEM_TARGET_H__ */

View file

@ -22,16 +22,14 @@
#include <jni.h>
#include "kernel.h"
#include "system.h"
extern JNIEnv *env_ptr;
extern jobject RockboxService_instance;
void telephony_init_device(void)
{
JNIEnv *env_ptr = getJavaEnvironment();
JNIEnv e = *env_ptr;
jclass class = e->FindClass(env_ptr, "org/rockbox/RockboxTelephony");
jmethodID constructor = e->GetMethodID(env_ptr, class, "<init>", "(Landroid/content/Context;)V");