mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-04 05:47:26 +00:00
native-activity: port android_app_entry (mainloop init) from C to Rust
This commit is contained in:
+3
-31
@@ -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;
|
||||
}
|
||||
|
||||
+3
-7
@@ -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)]
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user