(Android) Create android_app_userdata

This commit is contained in:
twinaphex 2015-05-01 20:21:52 +02:00
parent 50ab97d304
commit 2cc348a75b
3 changed files with 90 additions and 77 deletions

View File

@ -28,6 +28,7 @@
#include <retro_inline.h> #include <retro_inline.h>
struct android_app *g_android; struct android_app *g_android;
struct android_app_userdata *g_android_userdata;
static pthread_key_t thread_key; static pthread_key_t thread_key;
void android_app_write_cmd(struct android_app *android_app, int8_t cmd) void android_app_write_cmd(struct android_app *android_app, int8_t cmd)
@ -225,8 +226,8 @@ static void android_app_entry(void *data)
int ret_iterate; int ret_iterate;
struct android_app *android_app = (struct android_app*)data; struct android_app *android_app = (struct android_app*)data;
memset(&g_android, 0, sizeof(g_android)); g_android = android_app;
g_android = android_app; g_android_userdata = (struct android_app_userdata*)calloc(1, sizeof(*g_android_userdata));
slock_lock(android_app->mutex); slock_lock(android_app->mutex);
android_app->running = 1; android_app->running = 1;
@ -242,6 +243,11 @@ static void android_app_entry(void *data)
end: end:
main_exit(data); main_exit(data);
if (g_android_userdata)
free(g_android_userdata);
g_android_userdata = NULL;
exit(0); exit(0);
} }
@ -282,11 +288,6 @@ void ANativeActivity_onCreate(ANativeActivity* activity,
RARCH_ERR("Error initializing pthread_key\n"); RARCH_ERR("Error initializing pthread_key\n");
android_app = (struct android_app*)calloc(1, sizeof(*android_app)); android_app = (struct android_app*)calloc(1, sizeof(*android_app));
if (!android_app)
{
RARCH_ERR("Failed to initialize android_app\n");
return;
}
memset(android_app, 0, sizeof(struct android_app)); memset(android_app, 0, sizeof(struct android_app));
@ -447,6 +448,8 @@ static void frontend_android_get_environment_settings(int *argc,
jobject obj = NULL; jobject obj = NULL;
jstring jstr = NULL; jstring jstr = NULL;
struct android_app* android_app = (struct android_app*)data; struct android_app* android_app = (struct android_app*)data;
struct android_app_userdata *userdata =
(struct android_app_userdata*)g_android_userdata;
if (!android_app) if (!android_app)
return; return;
@ -470,14 +473,14 @@ static void frontend_android_get_environment_settings(int *argc,
RARCH_LOG("Android OS version (major : %d, minor : %d, rel : %d)\n", major, minor, rel); RARCH_LOG("Android OS version (major : %d, minor : %d, rel : %d)\n", major, minor, rel);
CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
android_app->getIntent); userdata->getIntent);
RARCH_LOG("Checking arguments passed from intent ...\n"); RARCH_LOG("Checking arguments passed from intent ...\n");
/* Config file. */ /* Config file. */
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "CONFIGFILE")); (*env)->NewStringUTF(env, "CONFIGFILE"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
static char config_path[PATH_MAX_LENGTH]; static char config_path[PATH_MAX_LENGTH];
const char *argv = NULL; const char *argv = NULL;
@ -495,23 +498,23 @@ static void frontend_android_get_environment_settings(int *argc,
} }
/* Current IME. */ /* Current IME. */
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "IME")); (*env)->NewStringUTF(env, "IME"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0); const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
strlcpy(android_app->current_ime, argv, strlcpy(userdata->current_ime, argv,
sizeof(android_app->current_ime)); sizeof(userdata->current_ime));
(*env)->ReleaseStringUTFChars(env, jstr, argv); (*env)->ReleaseStringUTFChars(env, jstr, argv);
RARCH_LOG("Current IME: [%s].\n", android_app->current_ime); RARCH_LOG("Current IME: [%s].\n", userdata->current_ime);
} }
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "USED")); (*env)->NewStringUTF(env, "USED"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
const char *argv = (*env)->GetStringUTFChars(env, jstr, 0); const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
bool used = (strcmp(argv, "false") == 0) ? false : true; bool used = (strcmp(argv, "false") == 0) ? false : true;
@ -521,10 +524,10 @@ static void frontend_android_get_environment_settings(int *argc,
} }
/* LIBRETRO. */ /* LIBRETRO. */
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "LIBRETRO")); (*env)->NewStringUTF(env, "LIBRETRO"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
static char core_path[PATH_MAX_LENGTH]; static char core_path[PATH_MAX_LENGTH];
const char *argv = NULL; const char *argv = NULL;
@ -541,10 +544,10 @@ static void frontend_android_get_environment_settings(int *argc,
} }
/* Content. */ /* Content. */
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "ROM")); (*env)->NewStringUTF(env, "ROM"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
static char path[PATH_MAX_LENGTH]; static char path[PATH_MAX_LENGTH];
const char *argv = NULL; const char *argv = NULL;
@ -565,10 +568,10 @@ static void frontend_android_get_environment_settings(int *argc,
} }
/* Content. */ /* Content. */
CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, CALL_OBJ_METHOD_PARAM(env, jstr, obj, userdata->getStringExtra,
(*env)->NewStringUTF(env, "DATADIR")); (*env)->NewStringUTF(env, "DATADIR"));
if (android_app->getStringExtra && jstr) if (userdata->getStringExtra && jstr)
{ {
static char path[PATH_MAX_LENGTH]; static char path[PATH_MAX_LENGTH];
const char *argv = NULL; const char *argv = NULL;
@ -647,6 +650,8 @@ static void frontend_android_deinit(void *data)
{ {
JNIEnv *env; JNIEnv *env;
struct android_app *android_app = (struct android_app*)data; struct android_app *android_app = (struct android_app*)data;
struct android_app_userdata *userdata =
(struct android_app_userdata*)g_android_userdata;
if (!android_app) if (!android_app)
return; return;
@ -656,9 +661,9 @@ static void frontend_android_deinit(void *data)
env = jni_thread_getenv(); env = jni_thread_getenv();
if (env && android_app->onRetroArchExit) if (env && userdata->onRetroArchExit)
CALL_VOID_METHOD(env, android_app->activity->clazz, CALL_VOID_METHOD(env, android_app->activity->clazz,
android_app->onRetroArchExit); userdata->onRetroArchExit);
if (android_app->inputQueue) if (android_app->inputQueue)
{ {
@ -831,6 +836,8 @@ static void frontend_android_init(void *data)
jclass class = NULL; jclass class = NULL;
jobject obj = NULL; jobject obj = NULL;
struct android_app* android_app = (struct android_app*)data; struct android_app* android_app = (struct android_app*)data;
struct android_app_userdata *userdata =
(struct android_app_userdata*)g_android_userdata;
if (!android_app) if (!android_app)
return; return;
@ -859,15 +866,15 @@ static void frontend_android_init(void *data)
return; return;
GET_OBJECT_CLASS(env, class, android_app->activity->clazz); GET_OBJECT_CLASS(env, class, android_app->activity->clazz);
GET_METHOD_ID(env, android_app->getIntent, class, GET_METHOD_ID(env, userdata->getIntent, class,
"getIntent", "()Landroid/content/Intent;"); "getIntent", "()Landroid/content/Intent;");
GET_METHOD_ID(env, android_app->onRetroArchExit, class, GET_METHOD_ID(env, userdata->onRetroArchExit, class,
"onRetroArchExit", "()V"); "onRetroArchExit", "()V");
CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
android_app->getIntent); userdata->getIntent);
GET_OBJECT_CLASS(env, class, obj); GET_OBJECT_CLASS(env, class, obj);
GET_METHOD_ID(env, android_app->getStringExtra, class, GET_METHOD_ID(env, userdata->getStringExtra, class,
"getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
frontend_android_get_version_sdk(&sdk); frontend_android_get_version_sdk(&sdk);

View File

@ -177,7 +177,10 @@ struct android_app
AInputQueue* pendingInputQueue; AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow; ANativeWindow* pendingWindow;
ARect pendingContentRect; ARect pendingContentRect;
};
struct android_app_userdata
{
unsigned accelerometer_event_rate; unsigned accelerometer_event_rate;
const ASensor* accelerometerSensor; const ASensor* accelerometerSensor;
uint64_t sensor_state_mask; uint64_t sensor_state_mask;
@ -192,7 +195,6 @@ struct android_app
jmethodID getPendingIntentFullPath; jmethodID getPendingIntentFullPath;
jmethodID getPendingIntentIME; jmethodID getPendingIntentIME;
android_input_state_t thread_state; android_input_state_t thread_state;
ASensorManager *sensorManager; ASensorManager *sensorManager;
ASensorEventQueue *sensorEventQueue; ASensorEventQueue *sensorEventQueue;
}; };
@ -397,5 +399,6 @@ JNIEnv *jni_thread_getenv(void);
void android_app_write_cmd(struct android_app *android_app, int8_t cmd); void android_app_write_cmd(struct android_app *android_app, int8_t cmd);
extern struct android_app *g_android; extern struct android_app *g_android;
extern struct android_app_userdata *g_android_userdata;
#endif /* _PLATFORM_ANDROID_H */ #endif /* _PLATFORM_ANDROID_H */

View File

@ -117,6 +117,7 @@ static void engine_handle_cmd(void)
{ {
int8_t cmd; int8_t cmd;
struct android_app *android_app = (struct android_app*)g_android; struct android_app *android_app = (struct android_app*)g_android;
struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
runloop_t *runloop = rarch_main_get_ptr(); runloop_t *runloop = rarch_main_get_ptr();
global_t *global = global_get_ptr(); global_t *global = global_get_ptr();
driver_t *driver = driver_get_ptr(); driver_t *driver = driver_get_ptr();
@ -213,23 +214,23 @@ static void engine_handle_cmd(void)
runloop->is_paused = false; runloop->is_paused = false;
runloop->is_idle = false; runloop->is_idle = false;
if ((android_app->sensor_state_mask if ((userdata->sensor_state_mask
& (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE)) & (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE))
&& android_app->accelerometerSensor == NULL && userdata->accelerometerSensor == NULL
&& driver->input_data) && driver->input_data)
android_input_set_sensor_state(driver->input_data, 0, android_input_set_sensor_state(driver->input_data, 0,
RETRO_SENSOR_ACCELEROMETER_ENABLE, RETRO_SENSOR_ACCELEROMETER_ENABLE,
android_app->accelerometer_event_rate); userdata->accelerometer_event_rate);
break; break;
case APP_CMD_LOST_FOCUS: case APP_CMD_LOST_FOCUS:
/* Avoid draining battery while app is not being used. */ /* Avoid draining battery while app is not being used. */
if ((android_app->sensor_state_mask if ((userdata->sensor_state_mask
& (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE)) & (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE))
&& android_app->accelerometerSensor != NULL && userdata->accelerometerSensor != NULL
&& driver->input_data) && driver->input_data)
android_input_set_sensor_state(driver->input_data, 0, android_input_set_sensor_state(driver->input_data, 0,
RETRO_SENSOR_ACCELEROMETER_DISABLE, RETRO_SENSOR_ACCELEROMETER_DISABLE,
android_app->accelerometer_event_rate); userdata->accelerometer_event_rate);
break; break;
case APP_CMD_DESTROY: case APP_CMD_DESTROY:
@ -361,7 +362,7 @@ static int android_input_get_id_index_from_name(android_input_state_t *android,
} }
static void handle_hotplug(android_input_state_t *android, static void handle_hotplug(android_input_state_t *android,
struct android_app *android_app, unsigned *port, unsigned id, struct android_app_userdata *userdata, unsigned *port, unsigned id,
int source) int source)
{ {
char device_name[256], name_buf[256]; char device_name[256], name_buf[256];
@ -502,12 +503,12 @@ static void handle_hotplug(android_input_state_t *android,
else if (device_name[0] != '\0') else if (device_name[0] != '\0')
strlcpy(name_buf, device_name, sizeof(name_buf)); strlcpy(name_buf, device_name, sizeof(name_buf));
if (strstr(android_app->current_ime, "net.obsidianx.android.mogaime")) if (strstr(userdata->current_ime, "net.obsidianx.android.mogaime"))
strlcpy(name_buf, android_app->current_ime, sizeof(name_buf)); strlcpy(name_buf, userdata->current_ime, sizeof(name_buf));
else if (strstr(android_app->current_ime, "com.ccpcreations.android.WiiUseAndroid")) else if (strstr(userdata->current_ime, "com.ccpcreations.android.WiiUseAndroid"))
strlcpy(name_buf, android_app->current_ime, sizeof(name_buf)); strlcpy(name_buf, userdata->current_ime, sizeof(name_buf));
else if (strstr(android_app->current_ime, "com.hexad.bluezime")) else if (strstr(userdata->current_ime, "com.hexad.bluezime"))
strlcpy(name_buf, android_app->current_ime, sizeof(name_buf)); strlcpy(name_buf, userdata->current_ime, sizeof(name_buf));
if (source == AINPUT_SOURCE_KEYBOARD && strcmp(name_buf, "Xperia Play")) if (source == AINPUT_SOURCE_KEYBOARD && strcmp(name_buf, "Xperia Play"))
strlcpy(name_buf, "RetroKeyboard", sizeof(name_buf)); strlcpy(name_buf, "RetroKeyboard", sizeof(name_buf));
@ -550,6 +551,7 @@ static void android_input_handle_input(android_input_state_t *android)
{ {
AInputEvent *event = NULL; AInputEvent *event = NULL;
struct android_app *android_app = (struct android_app*)g_android; struct android_app *android_app = (struct android_app*)g_android;
struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
/* Read all pending events. */ /* Read all pending events. */
while (AInputQueue_getEvent(android_app->inputQueue, &event) >= 0) while (AInputQueue_getEvent(android_app->inputQueue, &event) >= 0)
@ -562,7 +564,7 @@ static void android_input_handle_input(android_input_state_t *android)
int port = android_input_get_id_port(android, id, source); int port = android_input_get_id_port(android, id, source);
if (port < 0) if (port < 0)
handle_hotplug(android, android_app, handle_hotplug(android, userdata,
&android->pads_connected, id, source); &android->pads_connected, id, source);
switch (type_event) switch (type_event)
@ -589,14 +591,14 @@ static void android_input_handle_input(android_input_state_t *android)
static void android_input_handle_user(android_input_state_t *state) static void android_input_handle_user(android_input_state_t *state)
{ {
struct android_app *android_app = (struct android_app*)g_android; struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
if ((android_app->sensor_state_mask & (1ULL << if ((userdata->sensor_state_mask & (1ULL <<
RETRO_SENSOR_ACCELEROMETER_ENABLE)) RETRO_SENSOR_ACCELEROMETER_ENABLE))
&& android_app->accelerometerSensor) && userdata->accelerometerSensor)
{ {
ASensorEvent event; ASensorEvent event;
while (ASensorEventQueue_getEvents(android_app->sensorEventQueue, &event, 1) > 0) while (ASensorEventQueue_getEvents(userdata->sensorEventQueue, &event, 1) > 0)
{ {
state->accelerometer_state.x = event.acceleration.x; state->accelerometer_state.x = event.acceleration.x;
state->accelerometer_state.y = event.acceleration.y; state->accelerometer_state.y = event.acceleration.y;
@ -612,7 +614,7 @@ static void android_input_poll(void *data)
{ {
int ident; int ident;
android_input_t *android = (android_input_t*)data; android_input_t *android = (android_input_t*)data;
struct android_app *android_app = (struct android_app*)g_android; struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
while ((ident = while ((ident =
ALooper_pollAll((input_driver_key_pressed(RARCH_PAUSE_TOGGLE)) ALooper_pollAll((input_driver_key_pressed(RARCH_PAUSE_TOGGLE))
@ -622,10 +624,10 @@ static void android_input_poll(void *data)
switch (ident) switch (ident)
{ {
case LOOPER_ID_INPUT: case LOOPER_ID_INPUT:
android_input_handle_input(&android_app->thread_state); android_input_handle_input(&userdata->thread_state);
break; break;
case LOOPER_ID_USER: case LOOPER_ID_USER:
android_input_handle_user(&android_app->thread_state); android_input_handle_user(&userdata->thread_state);
break; break;
case LOOPER_ID_MAIN: case LOOPER_ID_MAIN:
engine_handle_cmd(); engine_handle_cmd();
@ -633,7 +635,7 @@ static void android_input_poll(void *data)
} }
} }
memcpy(&android->copy, &android_app->thread_state, sizeof(android->copy)); memcpy(&android->copy, &userdata->thread_state, sizeof(android->copy));
} }
bool android_run_events(void *data) bool android_run_events(void *data)
@ -716,11 +718,11 @@ static bool android_input_key_pressed(void *data, int key)
static void android_input_free_input(void *data) static void android_input_free_input(void *data)
{ {
struct android_app *android_app = (struct android_app*)g_android; struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
if (android_app->sensorManager) if (userdata->sensorManager)
ASensorManager_destroyEventQueue(android_app->sensorManager, ASensorManager_destroyEventQueue(userdata->sensorManager,
android_app->sensorEventQueue); userdata->sensorEventQueue);
free(data); free(data);
} }
@ -738,13 +740,14 @@ static uint64_t android_input_get_capabilities(void *data)
static void android_input_enable_sensor_manager(void *data) static void android_input_enable_sensor_manager(void *data)
{ {
struct android_app *android_app = (struct android_app*)g_android; struct android_app *android_app = (struct android_app*)g_android;
struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
android_app->sensorManager = ASensorManager_getInstance(); userdata->sensorManager = ASensorManager_getInstance();
android_app->accelerometerSensor = userdata->accelerometerSensor =
ASensorManager_getDefaultSensor(android_app->sensorManager, ASensorManager_getDefaultSensor(userdata->sensorManager,
ASENSOR_TYPE_ACCELEROMETER); ASENSOR_TYPE_ACCELEROMETER);
android_app->sensorEventQueue = userdata->sensorEventQueue =
ASensorManager_createEventQueue(android_app->sensorManager, ASensorManager_createEventQueue(userdata->sensorManager,
android_app->looper, LOOPER_ID_USER, NULL, NULL); android_app->looper, LOOPER_ID_USER, NULL, NULL);
} }
@ -752,7 +755,7 @@ static bool android_input_set_sensor_state(void *data, unsigned port,
enum retro_sensor_action action, unsigned event_rate) enum retro_sensor_action action, unsigned event_rate)
{ {
android_input_t *android = (android_input_t*)data; android_input_t *android = (android_input_t*)data;
struct android_app *android_app = (struct android_app*)g_android; struct android_app_userdata *userdata = (struct android_app_userdata*)g_android_userdata;
if (event_rate == 0) if (event_rate == 0)
event_rate = 60; event_rate = 60;
@ -760,33 +763,33 @@ static bool android_input_set_sensor_state(void *data, unsigned port,
switch (action) switch (action)
{ {
case RETRO_SENSOR_ACCELEROMETER_ENABLE: case RETRO_SENSOR_ACCELEROMETER_ENABLE:
if (!android_app->accelerometerSensor) if (!userdata->accelerometerSensor)
android_input_enable_sensor_manager(android); android_input_enable_sensor_manager(android);
if (android_app->accelerometerSensor) if (userdata->accelerometerSensor)
ASensorEventQueue_enableSensor(android_app->sensorEventQueue, ASensorEventQueue_enableSensor(userdata->sensorEventQueue,
android_app->accelerometerSensor); userdata->accelerometerSensor);
// events per second (in us). // events per second (in us).
if (android_app->accelerometerSensor) if (userdata->accelerometerSensor)
ASensorEventQueue_setEventRate(android_app->sensorEventQueue, ASensorEventQueue_setEventRate(userdata->sensorEventQueue,
android_app->accelerometerSensor, (1000L / event_rate) userdata->accelerometerSensor, (1000L / event_rate)
* 1000); * 1000);
android_app->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE); userdata->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE);
android_app->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE); userdata->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE);
return true; return true;
case RETRO_SENSOR_ACCELEROMETER_DISABLE: case RETRO_SENSOR_ACCELEROMETER_DISABLE:
if (android_app->accelerometerSensor) if (userdata->accelerometerSensor)
ASensorEventQueue_disableSensor(android_app->sensorEventQueue, ASensorEventQueue_disableSensor(userdata->sensorEventQueue,
android_app->accelerometerSensor); userdata->accelerometerSensor);
android_app->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE); userdata->sensor_state_mask &= ~(1ULL << RETRO_SENSOR_ACCELEROMETER_ENABLE);
android_app->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE); userdata->sensor_state_mask |= (1ULL << RETRO_SENSOR_ACCELEROMETER_DISABLE);
return true; return true;
default: default:
return false; break;
} }
return false; return false;