diff --git a/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.c b/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.c index 6ec55b2..4c070c4 100644 --- a/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.c +++ b/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.c @@ -228,48 +228,3 @@ void* android_app_entry(void* param) { android_app_destroy(android_app); return NULL; } - -// -------------------------------------------------------------------- -// Native activity interaction (called from main thread) -// -------------------------------------------------------------------- - - -void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { - if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { - LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); - } -} - -void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingInputQueue = inputQueue; - android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); - while (android_app->inputQueue != android_app->pendingInputQueue) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { - pthread_mutex_lock(&android_app->mutex); - if (android_app->pendingWindow != NULL) { - android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); - } - android_app->pendingWindow = window; - if (window != NULL) { - android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); - } - while (android_app->window != android_app->pendingWindow) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, cmd); - while (android_app->activityState != cmd) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} \ No newline at end of file diff --git a/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.h b/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.h index 5e7dca7..c4609ec 100644 --- a/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.h +++ b/android-activity/native-activity-csrc/native-activity/native_app_glue/android_native_app_glue.h @@ -334,12 +334,6 @@ void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); void android_app_attach_input_queue_looper(struct android_app* android_app); void android_app_detach_input_queue_looper(struct android_app* android_app); - -void android_app_write_cmd(struct android_app* android_app, int8_t cmd); -void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue); -void android_app_set_window(struct android_app* android_app, ANativeWindow* window); -void android_app_set_activity_state(struct android_app* android_app, int8_t cmd); - void* android_app_entry(void* param); /** diff --git a/android-activity/src/native_activity/ffi_aarch64.rs b/android-activity/src/native_activity/ffi_aarch64.rs index 3d81790..b8cf4b4 100644 --- a/android-activity/src/native_activity/ffi_aarch64.rs +++ b/android-activity/src/native_activity/ffi_aarch64.rs @@ -6328,28 +6328,6 @@ extern "C" { extern "C" { pub fn android_app_detach_input_queue_looper(android_app: *mut android_app); } -extern "C" { - pub fn android_app_create( - activity: *mut ANativeActivity, - savedState: *const ::std::os::raw::c_void, - savedStateSize: size_t, - ) -> *mut android_app; -} -extern "C" { - pub fn android_app_write_cmd(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_set_input(android_app: *mut android_app, inputQueue: *mut AInputQueue); -} -extern "C" { - pub fn android_app_set_window(android_app: *mut android_app, window: *mut ANativeWindow); -} -extern "C" { - pub fn android_app_set_activity_state(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_free(android_app: *mut android_app); -} extern "C" { pub fn android_app_entry(param: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; } diff --git a/android-activity/src/native_activity/ffi_arm.rs b/android-activity/src/native_activity/ffi_arm.rs index 00063db..9df36b6 100644 --- a/android-activity/src/native_activity/ffi_arm.rs +++ b/android-activity/src/native_activity/ffi_arm.rs @@ -6808,28 +6808,6 @@ extern "C" { extern "C" { pub fn android_app_detach_input_queue_looper(android_app: *mut android_app); } -extern "C" { - pub fn android_app_create( - activity: *mut ANativeActivity, - savedState: *const ::std::os::raw::c_void, - savedStateSize: size_t, - ) -> *mut android_app; -} -extern "C" { - pub fn android_app_write_cmd(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_set_input(android_app: *mut android_app, inputQueue: *mut AInputQueue); -} -extern "C" { - pub fn android_app_set_window(android_app: *mut android_app, window: *mut ANativeWindow); -} -extern "C" { - pub fn android_app_set_activity_state(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_free(android_app: *mut android_app); -} extern "C" { pub fn android_app_entry(param: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; } diff --git a/android-activity/src/native_activity/ffi_i686.rs b/android-activity/src/native_activity/ffi_i686.rs index 2d0df7b..0f8604c 100644 --- a/android-activity/src/native_activity/ffi_i686.rs +++ b/android-activity/src/native_activity/ffi_i686.rs @@ -8553,28 +8553,6 @@ extern "C" { extern "C" { pub fn android_app_detach_input_queue_looper(android_app: *mut android_app); } -extern "C" { - pub fn android_app_create( - activity: *mut ANativeActivity, - savedState: *const ::std::os::raw::c_void, - savedStateSize: size_t, - ) -> *mut android_app; -} -extern "C" { - pub fn android_app_write_cmd(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_set_input(android_app: *mut android_app, inputQueue: *mut AInputQueue); -} -extern "C" { - pub fn android_app_set_window(android_app: *mut android_app, window: *mut ANativeWindow); -} -extern "C" { - pub fn android_app_set_activity_state(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_free(android_app: *mut android_app); -} extern "C" { pub fn android_app_entry(param: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; } diff --git a/android-activity/src/native_activity/ffi_x86_64.rs b/android-activity/src/native_activity/ffi_x86_64.rs index b691ea3..e2fef1a 100644 --- a/android-activity/src/native_activity/ffi_x86_64.rs +++ b/android-activity/src/native_activity/ffi_x86_64.rs @@ -8571,28 +8571,6 @@ extern "C" { extern "C" { pub fn android_app_detach_input_queue_looper(android_app: *mut android_app); } -extern "C" { - pub fn android_app_create( - activity: *mut ANativeActivity, - savedState: *const ::std::os::raw::c_void, - savedStateSize: size_t, - ) -> *mut android_app; -} -extern "C" { - pub fn android_app_write_cmd(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_set_input(android_app: *mut android_app, inputQueue: *mut AInputQueue); -} -extern "C" { - pub fn android_app_set_window(android_app: *mut android_app, window: *mut ANativeWindow); -} -extern "C" { - pub fn android_app_set_activity_state(android_app: *mut android_app, cmd: i8); -} -extern "C" { - pub fn android_app_free(android_app: *mut android_app); -} extern "C" { pub fn android_app_entry(param: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; } diff --git a/android-activity/src/native_activity/mod.rs b/android-activity/src/native_activity/mod.rs index e7afb8c..42e7096 100644 --- a/android-activity/src/native_activity/mod.rs +++ b/android-activity/src/native_activity/mod.rs @@ -483,7 +483,7 @@ extern "C" fn android_app_main(arg: *mut libc::c_void) -> *mut libc::c_void { unsafe { ffi::android_app_entry(arg) as *mut _ } } -unsafe extern "C" fn android_app_create(activity: *mut ffi::ANativeActivity, +unsafe fn android_app_create(activity: *mut ffi::ANativeActivity, saved_state_in: *const libc::c_void, saved_state_size: libc::size_t) -> *mut ffi::android_app { let mut msgpipe: [libc::c_int; 2] = [ -1, -1 ]; @@ -551,9 +551,9 @@ unsafe extern "C" fn android_app_create(activity: *mut ffi::ANativeActivity, android_app } -unsafe extern "C" fn android_app_drop(android_app: *mut ffi::android_app) { +unsafe fn android_app_drop(android_app: *mut ffi::android_app) { libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _); - ffi::android_app_write_cmd(android_app, ffi::APP_CMD_DESTROY as i8); + android_app_write_cmd(android_app, ffi::APP_CMD_DESTROY as i8); while !(*android_app).destroyed == 0 { libc::pthread_cond_wait(&mut (*android_app).cond as *mut _, &mut (*android_app).mutex as *mut _); } @@ -568,6 +568,55 @@ unsafe extern "C" fn android_app_drop(android_app: *mut ffi::android_app) { // Box dropped here } +unsafe fn android_app_write_cmd(android_app: *mut ffi::android_app, cmd: i8) { + loop { + match libc::write((*android_app).msgwrite, &cmd as *const _ as *const _, 1) { + 1 => break, + -1 => { + let err = std::io::Error::last_os_error(); + if err.kind() != std::io::ErrorKind::Interrupted { + panic!("Failure writing android_app cmd: {}", err); + } + } + count => panic!("Spurious write of {count} bytes while writing android_app cmd") + } + } +} + +unsafe fn android_app_set_input(android_app: *mut ffi::android_app, input_queue: *mut ndk_sys::AInputQueue) { + libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _); + (*android_app).pendingInputQueue = input_queue; + android_app_write_cmd(android_app, ffi::APP_CMD_INPUT_CHANGED as i8); + while (*android_app).inputQueue != (*android_app).pendingInputQueue { + libc::pthread_cond_wait(&mut (*android_app).cond as *mut _, &mut (*android_app).mutex as *mut _); + } + libc::pthread_mutex_unlock(&mut (*android_app).mutex as *mut _); +} + +unsafe fn android_app_set_window(android_app: *mut ffi::android_app, window: *mut ndk_sys::ANativeWindow) { + libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _); + if (*android_app).pendingWindow != ptr::null_mut() { + android_app_write_cmd(android_app, ffi::APP_CMD_TERM_WINDOW as i8); + } + (*android_app).pendingWindow = window; + if window != ptr::null_mut() { + android_app_write_cmd(android_app, ffi::APP_CMD_INIT_WINDOW as i8); + } + while (*android_app).window != (*android_app).pendingWindow { + libc::pthread_cond_wait(&mut (*android_app).cond as *mut _, &mut (*android_app).mutex as *mut _); + } + libc::pthread_mutex_unlock(&mut (*android_app).mutex as *mut _); +} + +unsafe fn android_app_set_activity_state(android_app: *mut ffi::android_app, cmd: i8) { + libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _); + android_app_write_cmd(android_app, cmd); + while (*android_app).activityState as i8 != cmd { + libc::pthread_cond_wait(&mut (*android_app).cond as *mut _, &mut (*android_app).mutex as *mut _); + } + libc::pthread_mutex_unlock(&mut (*android_app).mutex as *mut _); +} + unsafe extern "C" fn on_destroy(activity: *mut ffi::ANativeActivity) { log::debug!("Destroy: {:p}\n", activity); @@ -580,13 +629,13 @@ unsafe extern "C" fn on_start(activity: *mut ffi::ANativeActivity) { log::debug!("Start: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_activity_state(android_app, ffi::APP_CMD_START as i8); + android_app_set_activity_state(android_app, ffi::APP_CMD_START as i8); } unsafe extern "C" fn on_resume(activity: *mut ffi::ANativeActivity) { log::debug!("Resume: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_activity_state(android_app, ffi::APP_CMD_RESUME as i8); + android_app_set_activity_state(android_app, ffi::APP_CMD_RESUME as i8); } unsafe extern "C" fn on_save_instance_state(activity: *mut ffi::ANativeActivity, out_len: *mut libc::size_t) -> *mut libc::c_void { @@ -596,7 +645,7 @@ unsafe extern "C" fn on_save_instance_state(activity: *mut ffi::ANativeActivity, log::debug!("SaveInstanceState: {:p}\n", activity); libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _); (*android_app).stateSaved = 0; - ffi::android_app_write_cmd(android_app, ffi::APP_CMD_SAVE_STATE as i8); + android_app_write_cmd(android_app, ffi::APP_CMD_SAVE_STATE as i8); while (*android_app).stateSaved == 0 { libc::pthread_cond_wait(&mut (*android_app).cond as *mut _, &mut (*android_app).mutex as *mut _); } @@ -616,56 +665,56 @@ unsafe extern "C" fn on_save_instance_state(activity: *mut ffi::ANativeActivity, unsafe extern "C" fn on_pause(activity: *mut ffi::ANativeActivity) { log::debug!("Pause: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_activity_state(android_app, ffi::APP_CMD_PAUSE as i8); + android_app_set_activity_state(android_app, ffi::APP_CMD_PAUSE as i8); } unsafe extern "C" fn on_stop(activity: *mut ffi::ANativeActivity) { log::debug!("Stop: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_activity_state(android_app, ffi::APP_CMD_STOP as i8); + android_app_set_activity_state(android_app, ffi::APP_CMD_STOP as i8); } unsafe extern "C" fn on_configuration_changed(activity: *mut ffi::ANativeActivity) { log::debug!("ConfigurationChanged: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_write_cmd(android_app, ffi::APP_CMD_CONFIG_CHANGED as i8); + android_app_write_cmd(android_app, ffi::APP_CMD_CONFIG_CHANGED as i8); } unsafe extern "C" fn on_low_memory(activity: *mut ffi::ANativeActivity) { log::debug!("LowMemory: {:p}\n", activity); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_write_cmd(android_app, ffi::APP_CMD_LOW_MEMORY as i8); + android_app_write_cmd(android_app, ffi::APP_CMD_LOW_MEMORY as i8); } unsafe extern "C" fn on_window_focus_changed(activity: *mut ffi::ANativeActivity, focused: libc::c_int) { log::debug!("WindowFocusChanged: {:p} -- {}\n", activity, focused); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_write_cmd(android_app, + android_app_write_cmd(android_app, if focused != 0 { ffi::APP_CMD_GAINED_FOCUS as i8 } else { ffi::APP_CMD_LOST_FOCUS as i8}); } unsafe extern "C" fn on_native_window_created(activity: *mut ffi::ANativeActivity, window: *mut ndk_sys::ANativeWindow) { log::debug!("NativeWindowCreated: {:p} -- {:p}\n", activity, window); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_window(android_app, window); + android_app_set_window(android_app, window); } unsafe extern "C" fn on_native_window_destroyed(activity: *mut ffi::ANativeActivity, window: *mut ndk_sys::ANativeWindow) { log::debug!("NativeWindowDestroyed: {:p} -- {:p}\n", activity, window); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_window(android_app, ptr::null_mut()); + android_app_set_window(android_app, ptr::null_mut()); } unsafe extern "C" fn on_input_queue_created(activity: *mut ffi::ANativeActivity, queue: *mut ndk_sys::AInputQueue) { log::debug!("InputQueueCreated: {:p} -- {:p}\n", activity, queue); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_input(android_app, queue); + android_app_set_input(android_app, queue); } unsafe extern "C" fn on_input_queue_destroyed(activity: *mut ffi::ANativeActivity, queue: *mut ndk_sys::AInputQueue) { log::debug!("InputQueueDestroyed: {:p} -- {:p}\n", activity, queue); let android_app: *mut ffi::android_app = (*activity).instance.cast(); - ffi::android_app_set_input(android_app, ptr::null_mut()); + android_app_set_input(android_app, ptr::null_mut()); } #[no_mangle]