//! DarkRoom Android entry point. //! //! The counterpart to `darkroom-desktop`'s `main`, with two differences that //! come from the platform rather than from choice: //! //! * There are no command-line paths. Android's SAF hands out document URIs, //! not filesystem paths (ARCH §6.9), so the viewer opens with an empty //! browsing list and the library grid is the only way in. //! * Logging goes to logcat. `env_logger` writes to stderr, which Android //! discards. // `slint::android` exists only when compiling for Android, so the whole entry // point is gated on the target rather than on a feature. Without this the // crate is still a workspace member on the host, and `cargo test --workspace` // fails to compile it — a build break that only ever appears off-device. #[cfg(target_os = "android")] /// TRACES: M-13 | M-14 /// Android application entry point, called by android-activity's glue. #[no_mangle] fn android_main(app: slint::android::AndroidApp) { android_logger::init_once( android_logger::Config::default() .with_max_level(log::LevelFilter::Info) .with_tag("DarkRoom"), ); // Panics go to stderr, and Android discards stderr. Without this hook a // worker thread that panics is invisible: the process survives, the // channel it was writing to closes, and the UI reports only that // something "failed unexpectedly" with no way to find out what. std::panic::set_hook(Box::new(|info| { log::error!("panic: {info}"); })); log::info!("DarkRoom v{}", env!("CARGO_PKG_VERSION")); // Before anything opens a store: Android has no $HOME and no XDG // directories, so the default guess resolves to a path the app cannot // write. Nothing failed loudly — the session list went to a doomed path, so // the account survived only as long as the process and backgrounding the app // lost the sign-in. `internal_data_path` is the app's private directory // (ARCH §6.9). match app.internal_data_path() { Some(dir) => { log::info!("data dir: {}", dir.display()); dr_sync_nextcloud::session::set_data_dir(dir); } None => log::error!("no internal data path; settings will not persist"), } if let Err(e) = slint::android::init(app) { log::error!("Slint Android backend failed to initialise: {e}"); return; } // Empty rather than the desktop's argv: see the module note above. // // Returning from `android_main` ends the process, so a failure here is // logged rather than propagated — there is no shell to show `Err` to. if let Err(e) = dr_ui::run(Vec::new()) { log::error!("DarkRoom exited with error: {e:#}"); } }