use jnim::*; use ndkm::Window as ANWin; use crate::app::bind_global_if_need; use crate::android; use android::view::SurfaceHolder as _; use super::{replace_anwin, with_win, with_win_mut, Key, WinRef}; pub trait WinActivity: JNameMaker + JPlainMarker + AsRef + AsRef { const ACTIVITY_NAME: &'static str; fn key(&self, env: &JEnv) -> Key; extern "C" fn activity_on_create(&self, env: &JEnv, _saved_instance_state: Option<&android::os::Bundle>) { let activity: &android::app::Activity = self.as_ref(); let key = self.key(env); bind_global_if_need(env, activity.get_application(env)); with_win_mut(key, |win| { let display_metrics = activity.get_resources(env)?.get_display_metrics(env)?; let scale_factor = display_metrics.r#density(env)?; win.scale_factor = Some(scale_factor); Some(()) }); with_win(key, |win| { let activity: &android::app::Activity = self.as_ref(); let window = activity.get_window(env)?; window.take_surface(env, self.as_ref()); win.delegate()?.on_create(win.win_ref()); Some(()) }); } extern "C" fn activity_on_start(&self, env: &JEnv) { let key = self.key(env); with_win(key, |win| { win.delegate()?.on_start(win.win_ref()); Some(()) }); } extern "C" fn activity_on_resume(&self, _env: &JEnv) {} extern "C" fn activity_on_pause(&self, _env: &JEnv) {} extern "C" fn activity_on_stop(&self, env: &JEnv) { let key = self.key(env); with_win(key, |win| { win.delegate()?.on_stop(win.win_ref()); Some(()) }); } extern "C" fn activity_on_destroy(&self, env: &JEnv) { let key = self.key(env); with_win(key, |win| { win.delegate()?.on_destroy(win.win_ref()); Some(()) }); } extern "C" fn surface_created(env: &JEnv, this: &Self, arg0: &android::view::SurfaceHolderObject) { let key = this.key(env); if let Some(surface) = arg0.get_surface(env) { let anwin = ANWin::from_java(env.as_sys(), surface.as_sys()); replace_anwin(key, anwin); } with_win(key, |win| { win.delegate()?.on_resume(win.win_ref()); Some(()) }); } extern "C" fn surface_changed(env: &JEnv, this: &Self, arg0: &android::view::SurfaceHolderObject, _: JInt, arg2: JInt, arg3: JInt) { let key = this.key(env); let old = if let Some(surface) = arg0.get_surface(env) { let anwin = ANWin::from_java(env.as_sys(), surface.as_sys()); replace_anwin(key, anwin) } else { None }; with_win(key, |win| { if old.as_ref() != win.anwin() { if let Some(old) = &old { win.delegate()?.on_pause(WinRef(Some(old), win)); } win.delegate()?.on_resume(win.win_ref()); } else { win.delegate()?.on_resize(win.win_ref(), (arg2 as _, arg3 as _)); } Some(()) }); } extern "C" fn surface_destroyed(env: &JEnv, this: &Self, _: &android::view::SurfaceHolderObject) { let key = this.key(env); let old = replace_anwin(key, None); with_win(key, |win| { win.delegate()?.on_pause(WinRef(old.as_ref(), win)); Some(()) }); } extern "C" fn surface_redraw_needed(env: &JEnv, this: &Self, _: &android::view::SurfaceHolderObject) { let key = this.key(env); with_win(key, |win| { log::debug!("surface_redraw_needed"); win.delegate()?.req_draw(win.win_ref(), win.frame_nano()); Some(()) }); } extern "C" fn configuration_changed(&self, _env: &JEnv, _: &android::content::res::Configuration) { // DO what? } }