diff --git a/crates/molotov-core/src/jni/activity.rs b/crates/molotov-core/src/jni/activity.rs new file mode 100644 index 0000000..db780ce --- /dev/null +++ b/crates/molotov-core/src/jni/activity.rs @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +#![allow(non_snake_case, dead_code)] +use super::env::JNIEnvWrapper; +use super::types::{JNIEnvPtr, JavaVMPtr}; +use super::vm::JavaVMWrapper; +use std::ffi::c_void; +use std::ptr; + +#[repr(C)] +pub struct ANativeActivityCallbacks { + pub onStart: Option, + pub onResume: Option, + pub onSaveInstanceState: Option *mut c_void>, + pub onPause: Option, + pub onStop: Option, + pub onDestroy: Option, + pub onWindowFocusChanged: Option, + pub onNativeWindowCreated: Option, + pub onNativeWindowResized: Option, + pub onNativeWindowRedrawNeeded: Option, + pub onNativeWindowDestroyed: Option, + pub onInputQueueCreated: Option, + pub onInputQueueDestroyed: Option, + pub onContentRectChanged: Option, + pub onConfigurationChanged: Option, + pub onLowMemory: Option, +} + +#[repr(C)] +pub struct ANativeActivity { + pub callbacks: *mut ANativeActivityCallbacks, + pub vm: JavaVMPtr, + pub env: JNIEnvPtr, + pub clazz: *mut c_void, + pub internalDataPath: *const libc::c_char, + pub externalDataPath: *const libc::c_char, + pub sdkVersion: i32, + pub instance: *mut c_void, + pub assetManager: *mut c_void, + pub obbPath: *const libc::c_char, +} + +pub struct ActivityRunner { + pub vm: JavaVMWrapper, + pub env: JNIEnvWrapper, + pub callbacks: Box, + pub activity: Box, + resumed: bool, +} + +impl Default for ActivityRunner { + fn default() -> Self { + Self::new() + } +} + +impl ActivityRunner { + pub fn new() -> Self { + let vm = JavaVMWrapper::new(); + let env = JNIEnvWrapper::new(); + + let mut callbacks = Box::new(ANativeActivityCallbacks { + onStart: None, + onResume: None, + onSaveInstanceState: None, + onPause: None, + onStop: None, + onDestroy: None, + onWindowFocusChanged: None, + onNativeWindowCreated: None, + onNativeWindowResized: None, + onNativeWindowRedrawNeeded: None, + onNativeWindowDestroyed: None, + onInputQueueCreated: None, + onInputQueueDestroyed: None, + onContentRectChanged: None, + onConfigurationChanged: None, + onLowMemory: None, + }); + + let activity = Box::new(ANativeActivity { + callbacks: &mut *callbacks as *mut ANativeActivityCallbacks, + vm: vm.as_raw_ptr(), + env: env.as_raw_ptr(), + clazz: ptr::null_mut(), + internalDataPath: ptr::null(), + externalDataPath: ptr::null(), + sdkVersion: 33, + instance: ptr::null_mut(), + assetManager: ptr::null_mut(), + obbPath: ptr::null(), + }); + + Self { + vm, + env, + callbacks, + activity, + resumed: false, + } + } + + pub fn is_resumed(&self) -> bool { + self.resumed + } + + pub fn trigger_resume(&mut self) { + self.resumed = true; + if let Some(cb) = self.callbacks.onResume { + unsafe { + cb(&mut *self.activity); + } + } + } + + pub fn trigger_pause(&mut self) { + self.resumed = false; + if let Some(cb) = self.callbacks.onPause { + unsafe { + cb(&mut *self.activity); + } + } + } +} diff --git a/crates/molotov-core/src/jni/mod.rs b/crates/molotov-core/src/jni/mod.rs index 38975d1..50f876c 100644 --- a/crates/molotov-core/src/jni/mod.rs +++ b/crates/molotov-core/src/jni/mod.rs @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later +pub mod activity; pub mod env; pub mod framework; pub mod objects; diff --git a/crates/molotov-core/tests/jni_activity_test.rs b/crates/molotov-core/tests/jni_activity_test.rs new file mode 100644 index 0000000..224c91e --- /dev/null +++ b/crates/molotov-core/tests/jni_activity_test.rs @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use molotov_core::jni::activity::ActivityRunner; + +#[test] +fn test_activity_runner_lifecycle_callbacks() { + let mut runner = ActivityRunner::new(); + assert_eq!(runner.is_resumed(), false); + + runner.trigger_resume(); + assert_eq!(runner.is_resumed(), true); + + runner.trigger_pause(); + assert_eq!(runner.is_resumed(), false); +}