(Android) Native activity updates

This commit is contained in:
twinaphex 2015-12-02 08:54:24 +01:00
parent d171c831c3
commit 986e4bf40d
3 changed files with 131 additions and 59 deletions

View File

@ -630,6 +630,34 @@ static void onResume(ANativeActivity* activity)
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)
{
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);
}
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)
{
RARCH_LOG("WindowFocusChanged: %p -- %d\n", activity, focused);
@ -748,59 +783,34 @@ end:
exit(0);
}
/*
* Native activity interaction (called from main thread)
**/
void ANativeActivity_onCreate(ANativeActivity* activity,
void* savedState, size_t savedStateSize)
static struct android_app* android_app_create(ANativeActivity* activity,
void* savedState, size_t savedStateSize)
{
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)
{
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->mutex = slock_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))
{
RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
activity->instance = NULL;
return NULL;
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
@ -813,7 +823,40 @@ void ANativeActivity_onCreate(ANativeActivity* activity,
scond_wait(android_app->cond, 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);
}

View File

@ -72,23 +72,59 @@ char sdcard_dir[PATH_MAX_LENGTH];
struct android_app
{
/* The ANativeActivity object instance that this app is running in. */
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;
/* When non-NULL, this is the input queue from which the app will
* receive user input events. */
AInputQueue* inputQueue;
AInputQueue* pendingInputQueue;
/* When non-NULL, this is the window surface that the app can draw in. */
ANativeWindow* window;
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;
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 msgread;
int msgwrite;
sthread_t *thread;
int running;
int stateSaved;
int destroyed;
bool unfocused;
unsigned accelerometer_event_rate;
const ASensor* accelerometerSensor;
uint64_t sensor_state_mask;
sthread_t *thread;
char current_ime[PATH_MAX_LENGTH];
jmethodID getIntent;
jmethodID onRetroArchExit;

View File

@ -241,7 +241,9 @@ static void android_input_poll_main_cmd(void)
rarch_system_info_t *system = rarch_system_info_get_ptr();
if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd))
{
cmd = -1;
}
switch (cmd)
{
@ -276,27 +278,16 @@ static void android_input_poll_main_cmd(void)
event_command(EVENT_CMD_REINIT);
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:
slock_lock(android_app->mutex);
android_app->activityState = cmd;
scond_broadcast(android_app->cond);
slock_unlock(android_app->mutex);
break;
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:
slock_lock(android_app->mutex);
android_app->activityState = cmd;
scond_broadcast(android_app->cond);
slock_unlock(android_app->mutex);
break;
case APP_CMD_STOP:
slock_lock(android_app->mutex);
android_app->activityState = cmd;
@ -359,7 +350,9 @@ static void android_input_poll_main_cmd(void)
break;
case APP_CMD_DESTROY:
RARCH_LOG("APP_CMD_DESTROY\n");
system->shutdown = true;
android_app->destroyRequested = 1;
break;
}
}