native-activity: port android_app_entry (mainloop init) from C to Rust

This commit is contained in:
Robert Bragg
2022-10-01 16:08:55 +01:00
parent 1314210be4
commit 1507b37425
7 changed files with 73 additions and 59 deletions
@@ -61,7 +61,7 @@ int8_t android_app_read_cmd(struct android_app* android_app) {
return -1;
}
static void print_cur_config(struct android_app* android_app) {
void print_cur_config(struct android_app* android_app) {
char lang[2], country[2];
AConfiguration_getLanguage(android_app->config, lang);
AConfiguration_getCountry(android_app->config, country);
@@ -180,7 +180,7 @@ void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
}
}
static void android_app_destroy(struct android_app* android_app) {
void android_app_destroy(struct android_app* android_app) {
LOGV("android_app_destroy!");
free_saved_state(android_app);
pthread_mutex_lock(&android_app->mutex);
@@ -194,37 +194,9 @@ static void android_app_destroy(struct android_app* android_app) {
// Can't touch android_app object after this.
}
static void process_cmd(struct android_app* app, __attribute__((unused)) struct android_poll_source* source) {
void process_cmd(struct android_app* app, __attribute__((unused)) struct android_poll_source* source) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
android_app_post_exec_cmd(app, cmd);
}
void* android_app_entry(void* param) {
struct android_app* android_app = (struct android_app*)param;
android_app->config = AConfiguration_new();
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
print_cur_config(android_app);
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
android_app->cmdPollSource.app = android_app;
android_app->cmdPollSource.process = process_cmd;
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
&android_app->cmdPollSource);
android_app->looper = looper;
pthread_mutex_lock(&android_app->mutex);
android_app->running = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
_rust_glue_entry(android_app);
android_app_destroy(android_app);
return NULL;
}
@@ -334,13 +334,9 @@ 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_entry(void* param);
/**
* This is the function that application code must implement, representing
* the main entry to the app.
*/
extern void _rust_glue_entry(struct android_app* app);
void print_cur_config(struct android_app* android_app);
void process_cmd(struct android_app* app, __attribute__((unused)) struct android_poll_source* source);
void android_app_destroy(struct android_app* android_app);
#ifdef __cplusplus
}
@@ -6329,11 +6329,12 @@ extern "C" {
pub fn android_app_detach_input_queue_looper(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;
pub fn print_cur_config(android_app: *mut android_app);
}
extern "C" {
#[doc = " This is the function that application code must implement, representing"]
#[doc = " the main entry to the app."]
pub fn _rust_glue_entry(app: *mut android_app);
pub fn process_cmd(app: *mut android_app, source: *mut android_poll_source);
}
extern "C" {
pub fn android_app_destroy(android_app: *mut android_app);
}
pub type __uint128_t = u128;
@@ -6809,10 +6809,11 @@ extern "C" {
pub fn android_app_detach_input_queue_looper(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;
pub fn print_cur_config(android_app: *mut android_app);
}
extern "C" {
#[doc = " This is the function that application code must implement, representing"]
#[doc = " the main entry to the app."]
pub fn _rust_glue_entry(app: *mut android_app);
pub fn process_cmd(app: *mut android_app, source: *mut android_poll_source);
}
extern "C" {
pub fn android_app_destroy(android_app: *mut android_app);
}
@@ -8554,11 +8554,12 @@ extern "C" {
pub fn android_app_detach_input_queue_looper(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;
pub fn print_cur_config(android_app: *mut android_app);
}
extern "C" {
#[doc = " This is the function that application code must implement, representing"]
#[doc = " the main entry to the app."]
pub fn _rust_glue_entry(app: *mut android_app);
pub fn process_cmd(app: *mut android_app, source: *mut android_poll_source);
}
extern "C" {
pub fn android_app_destroy(android_app: *mut android_app);
}
pub type __builtin_va_list = *mut ::std::os::raw::c_char;
@@ -8572,12 +8572,13 @@ extern "C" {
pub fn android_app_detach_input_queue_looper(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;
pub fn print_cur_config(android_app: *mut android_app);
}
extern "C" {
#[doc = " This is the function that application code must implement, representing"]
#[doc = " the main entry to the app."]
pub fn _rust_glue_entry(app: *mut android_app);
pub fn process_cmd(app: *mut android_app, source: *mut android_poll_source);
}
extern "C" {
pub fn android_app_destroy(android_app: *mut android_app);
}
pub type __builtin_va_list = [__va_list_tag; 1usize];
#[repr(C)]
+47 -5
View File
@@ -479,10 +479,49 @@ impl AndroidAppInner {
}
}
////////////////////////////
// Rust-side event loop
////////////////////////////
extern "C" fn android_app_main(arg: *mut libc::c_void) -> *mut libc::c_void {
unsafe { ffi::android_app_entry(arg) as *mut _ }
unsafe {
let android_app: *mut ffi::android_app = arg.cast();
(*android_app).config = ndk_sys::AConfiguration_new();
ndk_sys::AConfiguration_fromAssetManager((*android_app).config, (*(*android_app).activity).assetManager);
ffi::print_cur_config(android_app);
(*android_app).cmdPollSource.id = ffi::LOOPER_ID_MAIN as i32;
(*android_app).cmdPollSource.app = android_app;
(*android_app).cmdPollSource.process = Some(ffi::process_cmd);
let looper = ndk_sys::ALooper_prepare(ndk_sys::ALOOPER_PREPARE_ALLOW_NON_CALLBACKS as libc::c_int);
ndk_sys::ALooper_addFd(looper, (*android_app).msgread, ffi::LOOPER_ID_MAIN as libc::c_int, ndk_sys::ALOOPER_EVENT_INPUT as libc::c_int, None,
&mut (*android_app).cmdPollSource as *mut _ as *mut _);
(*android_app).looper = looper;
libc::pthread_mutex_lock(&mut (*android_app).mutex as *mut _);
(*android_app).running = 1;
libc::pthread_cond_broadcast(&mut (*android_app).cond as *mut _);
libc::pthread_mutex_unlock(&mut (*android_app).mutex as *mut _);
_rust_glue_entry(android_app);
ffi::android_app_destroy(android_app);
ptr::null_mut()
}
}
///////////////////////////////
// Java-side callback handling
///////////////////////////////
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
{
@@ -575,10 +614,14 @@ unsafe fn android_app_write_cmd(android_app: *mut ffi::android_app, cmd: i8) {
-1 => {
let err = std::io::Error::last_os_error();
if err.kind() != std::io::ErrorKind::Interrupted {
panic!("Failure writing android_app cmd: {}", err);
log::error!("Failure writing android_app cmd: {}", err);
return;
}
}
count => panic!("Spurious write of {count} bytes while writing android_app cmd")
count => {
log::error!("Spurious write of {count} bytes while writing android_app cmd");
return;
}
}
}
}
@@ -762,8 +805,7 @@ extern "Rust" {
// This is a spring board between android_native_app_glue and the user's
// `app_main` function. This is run on a dedicated thread spawned
// by android_native_app_glue.
#[no_mangle]
pub unsafe extern "C" fn _rust_glue_entry(app: *mut ffi::android_app) {
pub unsafe fn _rust_glue_entry(app: *mut ffi::android_app) {
// Maybe make this stdout/stderr redirection an optional / opt-in feature?...
let mut logpipe: [RawFd; 2] = Default::default();
libc::pipe(logpipe.as_mut_ptr());