mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-04 05:47:26 +00:00
native-activity: complete port of sender/java-side C code to Rust
This commit is contained in:
-45
@@ -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);
|
||||
}
|
||||
-6
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user