mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 13:20:43 +00:00
(Android) Native activity updates
This commit is contained in:
parent
d171c831c3
commit
986e4bf40d
@ -630,6 +630,34 @@ static void onResume(ANativeActivity* activity)
|
|||||||
activity->instance, APP_CMD_RESUME);
|
activity->instance, APP_CMD_RESUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen)
|
||||||
|
{
|
||||||
|
void* savedState = NULL;
|
||||||
|
struct android_app* android_app = (struct android_app*)activity->instance;
|
||||||
|
|
||||||
|
RARCH_LOG("SaveInstanceState: %p\n", activity);
|
||||||
|
|
||||||
|
slock_lock(android_app->mutex);
|
||||||
|
|
||||||
|
android_app->stateSaved = 0;
|
||||||
|
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
|
||||||
|
|
||||||
|
while (!android_app->stateSaved)
|
||||||
|
scond_wait(android_app->cond, android_app->mutex);
|
||||||
|
|
||||||
|
if (android_app->savedState != NULL)
|
||||||
|
{
|
||||||
|
savedState = android_app->savedState;
|
||||||
|
*outLen = android_app->savedStateSize;
|
||||||
|
android_app->savedState = NULL;
|
||||||
|
android_app->savedStateSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
slock_unlock(android_app->mutex);
|
||||||
|
|
||||||
|
return savedState;
|
||||||
|
}
|
||||||
|
|
||||||
static void onPause(ANativeActivity* activity)
|
static void onPause(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
RARCH_LOG("Pause: %p\n", activity);
|
RARCH_LOG("Pause: %p\n", activity);
|
||||||
@ -656,6 +684,13 @@ static void onConfigurationChanged(ANativeActivity *activity)
|
|||||||
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
|
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void onLowMemory(ANativeActivity* activity)
|
||||||
|
{
|
||||||
|
struct android_app* android_app = (struct android_app*)activity->instance;
|
||||||
|
RARCH_LOG("LowMemory: %p\n", activity);
|
||||||
|
android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
static void onWindowFocusChanged(ANativeActivity* activity, int focused)
|
static void onWindowFocusChanged(ANativeActivity* activity, int focused)
|
||||||
{
|
{
|
||||||
RARCH_LOG("WindowFocusChanged: %p -- %d\n", activity, focused);
|
RARCH_LOG("WindowFocusChanged: %p -- %d\n", activity, focused);
|
||||||
@ -748,59 +783,34 @@ end:
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static struct android_app* android_app_create(ANativeActivity* activity,
|
||||||
* Native activity interaction (called from main thread)
|
void* savedState, size_t savedStateSize)
|
||||||
**/
|
|
||||||
|
|
||||||
void ANativeActivity_onCreate(ANativeActivity* activity,
|
|
||||||
void* savedState, size_t savedStateSize)
|
|
||||||
{
|
{
|
||||||
int msgpipe[2];
|
int msgpipe[2];
|
||||||
struct android_app* android_app;
|
struct android_app *android_app =
|
||||||
|
(struct android_app*)calloc(1, sizeof(*android_app));
|
||||||
|
|
||||||
(void)savedState;
|
|
||||||
(void)savedStateSize;
|
|
||||||
|
|
||||||
RARCH_LOG("Creating Native Activity: %p\n", activity);
|
|
||||||
activity->callbacks->onDestroy = onDestroy;
|
|
||||||
activity->callbacks->onStart = onStart;
|
|
||||||
activity->callbacks->onResume = onResume;
|
|
||||||
activity->callbacks->onSaveInstanceState = NULL;
|
|
||||||
activity->callbacks->onPause = onPause;
|
|
||||||
activity->callbacks->onStop = onStop;
|
|
||||||
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
|
|
||||||
activity->callbacks->onLowMemory = NULL;
|
|
||||||
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
|
|
||||||
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
|
|
||||||
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
|
|
||||||
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
|
|
||||||
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
|
|
||||||
|
|
||||||
/* These are set only for the native activity,
|
|
||||||
* and are reset when it ends. */
|
|
||||||
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON
|
|
||||||
| AWINDOW_FLAG_FULLSCREEN, 0);
|
|
||||||
|
|
||||||
if (pthread_key_create(&thread_key, jni_thread_destruct))
|
|
||||||
RARCH_ERR("Error initializing pthread_key\n");
|
|
||||||
|
|
||||||
android_app = (struct android_app*)calloc(1, sizeof(*android_app));
|
|
||||||
if (!android_app)
|
if (!android_app)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize android_app\n");
|
RARCH_ERR("Failed to initialize android_app\n");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(android_app, 0, sizeof(struct android_app));
|
|
||||||
|
|
||||||
android_app->activity = activity;
|
android_app->activity = activity;
|
||||||
|
|
||||||
android_app->mutex = slock_new();
|
android_app->mutex = slock_new();
|
||||||
android_app->cond = scond_new();
|
android_app->cond = scond_new();
|
||||||
|
|
||||||
|
if (savedState != NULL)
|
||||||
|
{
|
||||||
|
android_app->savedState = malloc(savedStateSize);
|
||||||
|
android_app->savedStateSize = savedStateSize;
|
||||||
|
memcpy(android_app->savedState, savedState, savedStateSize);
|
||||||
|
}
|
||||||
|
|
||||||
if (pipe(msgpipe))
|
if (pipe(msgpipe))
|
||||||
{
|
{
|
||||||
RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
|
RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
|
||||||
activity->instance = NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
android_app->msgread = msgpipe[0];
|
android_app->msgread = msgpipe[0];
|
||||||
android_app->msgwrite = msgpipe[1];
|
android_app->msgwrite = msgpipe[1];
|
||||||
@ -813,7 +823,40 @@ void ANativeActivity_onCreate(ANativeActivity* activity,
|
|||||||
scond_wait(android_app->cond, android_app->mutex);
|
scond_wait(android_app->cond, android_app->mutex);
|
||||||
slock_unlock(android_app->mutex);
|
slock_unlock(android_app->mutex);
|
||||||
|
|
||||||
activity->instance = android_app;
|
return android_app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Native activity interaction (called from main thread)
|
||||||
|
**/
|
||||||
|
|
||||||
|
void ANativeActivity_onCreate(ANativeActivity* activity,
|
||||||
|
void* savedState, size_t savedStateSize)
|
||||||
|
{
|
||||||
|
RARCH_LOG("Creating Native Activity: %p\n", activity);
|
||||||
|
activity->callbacks->onDestroy = onDestroy;
|
||||||
|
activity->callbacks->onStart = onStart;
|
||||||
|
activity->callbacks->onResume = onResume;
|
||||||
|
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
|
||||||
|
activity->callbacks->onPause = onPause;
|
||||||
|
activity->callbacks->onStop = onStop;
|
||||||
|
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
|
||||||
|
activity->callbacks->onLowMemory = onLowMemory;
|
||||||
|
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
|
||||||
|
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
|
||||||
|
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
|
||||||
|
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
|
||||||
|
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
|
||||||
|
|
||||||
|
/* These are set only for the native activity,
|
||||||
|
* and are reset when it ends. */
|
||||||
|
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON
|
||||||
|
| AWINDOW_FLAG_FULLSCREEN, 0);
|
||||||
|
|
||||||
|
if (pthread_key_create(&thread_key, jni_thread_destruct))
|
||||||
|
RARCH_ERR("Error initializing pthread_key\n");
|
||||||
|
|
||||||
|
activity->instance = android_app_create(activity, savedState, savedStateSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,23 +72,59 @@ char sdcard_dir[PATH_MAX_LENGTH];
|
|||||||
|
|
||||||
struct android_app
|
struct android_app
|
||||||
{
|
{
|
||||||
|
/* The ANativeActivity object instance that this app is running in. */
|
||||||
ANativeActivity* activity;
|
ANativeActivity* activity;
|
||||||
|
|
||||||
|
/* This is the last instance's saved state, as provided at creation time.
|
||||||
|
* It is NULL if there was no state. You can use this as you need; the
|
||||||
|
* memory will remain around until you call android_app_exec_cmd() for
|
||||||
|
* APP_CMD_RESUME, at which point it will be freed and savedState set to NULL.
|
||||||
|
* These variables should only be changed when processing a APP_CMD_SAVE_STATE,
|
||||||
|
* at which point they will be initialized to NULL and you can malloc your
|
||||||
|
* state and place the information here. In that case the memory will be
|
||||||
|
* freed for you later.
|
||||||
|
*/
|
||||||
|
void* savedState;
|
||||||
|
size_t savedStateSize;
|
||||||
|
|
||||||
|
/* The ALooper associated with the app's thread. */
|
||||||
ALooper* looper;
|
ALooper* looper;
|
||||||
|
|
||||||
|
/* When non-NULL, this is the input queue from which the app will
|
||||||
|
* receive user input events. */
|
||||||
AInputQueue* inputQueue;
|
AInputQueue* inputQueue;
|
||||||
|
|
||||||
AInputQueue* pendingInputQueue;
|
AInputQueue* pendingInputQueue;
|
||||||
|
|
||||||
|
/* When non-NULL, this is the window surface that the app can draw in. */
|
||||||
ANativeWindow* window;
|
ANativeWindow* window;
|
||||||
|
|
||||||
ANativeWindow* pendingWindow;
|
ANativeWindow* pendingWindow;
|
||||||
|
|
||||||
|
/* This is non-zero when the application's NativeActivity is being
|
||||||
|
* destroyed and waiting for the app thread to complete. */
|
||||||
|
int destroyRequested;
|
||||||
|
|
||||||
slock_t *mutex;
|
slock_t *mutex;
|
||||||
scond_t *cond;
|
scond_t *cond;
|
||||||
|
|
||||||
|
/* Current state of the app's activity. May be either APP_CMD_START,
|
||||||
|
* APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. */
|
||||||
int activityState;
|
int activityState;
|
||||||
|
|
||||||
int msgread;
|
int msgread;
|
||||||
int msgwrite;
|
int msgwrite;
|
||||||
|
|
||||||
|
sthread_t *thread;
|
||||||
|
|
||||||
int running;
|
int running;
|
||||||
|
int stateSaved;
|
||||||
|
int destroyed;
|
||||||
|
|
||||||
bool unfocused;
|
bool unfocused;
|
||||||
unsigned accelerometer_event_rate;
|
unsigned accelerometer_event_rate;
|
||||||
const ASensor* accelerometerSensor;
|
const ASensor* accelerometerSensor;
|
||||||
uint64_t sensor_state_mask;
|
uint64_t sensor_state_mask;
|
||||||
sthread_t *thread;
|
|
||||||
char current_ime[PATH_MAX_LENGTH];
|
char current_ime[PATH_MAX_LENGTH];
|
||||||
jmethodID getIntent;
|
jmethodID getIntent;
|
||||||
jmethodID onRetroArchExit;
|
jmethodID onRetroArchExit;
|
||||||
|
@ -241,7 +241,9 @@ static void android_input_poll_main_cmd(void)
|
|||||||
rarch_system_info_t *system = rarch_system_info_get_ptr();
|
rarch_system_info_t *system = rarch_system_info_get_ptr();
|
||||||
|
|
||||||
if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd))
|
if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd))
|
||||||
|
{
|
||||||
cmd = -1;
|
cmd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
@ -276,27 +278,16 @@ static void android_input_poll_main_cmd(void)
|
|||||||
event_command(EVENT_CMD_REINIT);
|
event_command(EVENT_CMD_REINIT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case APP_CMD_SAVE_STATE:
|
||||||
|
slock_lock(android_app->mutex);
|
||||||
|
android_app->stateSaved = 1;
|
||||||
|
scond_broadcast(android_app->cond);
|
||||||
|
slock_unlock(android_app->mutex);
|
||||||
|
break;
|
||||||
|
|
||||||
case APP_CMD_RESUME:
|
case APP_CMD_RESUME:
|
||||||
slock_lock(android_app->mutex);
|
|
||||||
android_app->activityState = cmd;
|
|
||||||
scond_broadcast(android_app->cond);
|
|
||||||
slock_unlock(android_app->mutex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case APP_CMD_START:
|
case APP_CMD_START:
|
||||||
slock_lock(android_app->mutex);
|
|
||||||
android_app->activityState = cmd;
|
|
||||||
scond_broadcast(android_app->cond);
|
|
||||||
slock_unlock(android_app->mutex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case APP_CMD_PAUSE:
|
case APP_CMD_PAUSE:
|
||||||
slock_lock(android_app->mutex);
|
|
||||||
android_app->activityState = cmd;
|
|
||||||
scond_broadcast(android_app->cond);
|
|
||||||
slock_unlock(android_app->mutex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case APP_CMD_STOP:
|
case APP_CMD_STOP:
|
||||||
slock_lock(android_app->mutex);
|
slock_lock(android_app->mutex);
|
||||||
android_app->activityState = cmd;
|
android_app->activityState = cmd;
|
||||||
@ -359,7 +350,9 @@ static void android_input_poll_main_cmd(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case APP_CMD_DESTROY:
|
case APP_CMD_DESTROY:
|
||||||
|
RARCH_LOG("APP_CMD_DESTROY\n");
|
||||||
system->shutdown = true;
|
system->shutdown = true;
|
||||||
|
android_app->destroyRequested = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user