From d277ae955191d4da24333c11027a297106554752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gianguido=20Sor=C3=A0?= Date: Fri, 4 Nov 2022 17:31:27 +0100 Subject: [PATCH] feat: show boot process notifications for PDDB This commit shows two notifications: 1. as soon as the device boots, a notification greets the user and tells them everything is fine, the device is booting 2. as soon as the user enters (or doesn't) enter the password, a notification tell the user Xous is loading and mounting PDDB I spent too much time on this but I believe it's a nice UX improvement. --- services/pddb/src/main.rs | 40 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/services/pddb/src/main.rs b/services/pddb/src/main.rs index 4e4944e70..2f31e039b 100644 --- a/services/pddb/src/main.rs +++ b/services/pddb/src/main.rs @@ -394,7 +394,7 @@ use std::collections::{HashMap, BTreeSet}; use std::io::ErrorKind; use core::fmt::Write; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use locales::t; @@ -490,6 +490,34 @@ fn wrapped_main() -> ! { } }); + let hide_startingup_notif = Arc::new(Mutex::new(false)); + let hide_startingup_notif_clone = hide_startingup_notif.clone(); + + std::thread::spawn(move || { + // For some weird reason spawning a dynamic notification without waiting 800ms in a separate thread + // makes it impossible to read, because it gets covered by hundreds of those modal security lines (???). + // This thread waits on hide_startingup_notif to become true, then disimsses the dynamic notification that it created + // previously. + // To allow other threads to do work, yield to kernel every time the variable is read as false. + + let xns = xous_names::XousNames::new().unwrap(); + let modals = modals::Modals::new(&xns).expect("can't connect to Modals server"); + + std::thread::sleep(std::time::Duration::from_millis(1000)); + + modals.dynamic_notification(Some("Starting up..."), Some("Precursor is booting up, please wait.")).unwrap(); + + loop { + if *hide_startingup_notif_clone.lock().unwrap() { + modals.dynamic_notification_close().unwrap(); + break; + } + + xous::yield_slice(); + }; + }); + + // OS-specific PDDB driver let mut pddb_os = PddbOs::new(Rc::clone(&entropy), pw_cid); // storage for the basis cache @@ -656,6 +684,8 @@ fn wrapped_main() -> ! { // - code = 2 -> mount failed, because too many PINs were retried. `count` is the number of retries. // If we need more nuance out of this routine, consider creating a custom public enum type to help marshall this. Opcode::TryMount => xous::msg_blocking_scalar_unpack!(msg, _, _, _, _, { + *hide_startingup_notif.lock().unwrap() = true; + if basis_cache.basis_count() > 0 { xous::return_scalar2(msg.sender, 0, 0).expect("couldn't return scalar"); } else { @@ -669,6 +699,8 @@ fn wrapped_main() -> ! { } else { match ensure_password(&modals, &mut pddb_os, pw_cid) { PasswordState::Correct => { + modals.dynamic_notification(Some("Starting up..."), Some("Mounting PDDB, please wait.")).unwrap(); + if try_mount_or_format(&modals, &mut pddb_os, &mut basis_cache, PasswordState::Correct, time_resetter) { is_mounted.store(true, Ordering::SeqCst); for requester in mount_notifications.drain(..) { @@ -680,8 +712,12 @@ fn wrapped_main() -> ! { } else { xous::return_scalar2(msg.sender, 1, 0).expect("couldn't return scalar"); } + + modals.dynamic_notification_close().unwrap(); }, PasswordState::Uninit => { + modals.dynamic_notification(Some("Starting up..."), Some("Mounting PDDB, please wait.")).unwrap(); + if try_mount_or_format(&modals, &mut pddb_os, &mut basis_cache, PasswordState::Uninit, time_resetter) { for requester in mount_notifications.drain(..) { xous::return_scalar2(requester, 0, 0).expect("couldn't return scalar"); @@ -693,6 +729,8 @@ fn wrapped_main() -> ! { } else { xous::return_scalar2(msg.sender, 1, 0).expect("couldn't return scalar"); } + + modals.dynamic_notification_close().unwrap(); }, PasswordState::ForcedAbort(failcount) => { xous::return_scalar2(msg.sender, 2,