Skip to content

Commit

Permalink
add automounter to shellchat, and initial wait message
Browse files Browse the repository at this point in the history
The initial wait message is drawn directly under where
the modals would appear, so the message "goes away"
when modals pop up.

There's still a bit of trickiness around the timing of
some of the calls. Attempting to mount the PDDB too early
before all the contexts have been registered leads to
a lot of needless defacing.

Also, the final redraw needs a short delay to allow
the system to foreground shellchat again after closing
the modals.
  • Loading branch information
bunnie committed Nov 5, 2022
1 parent e240ca6 commit a56b8c8
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
7 changes: 7 additions & 0 deletions services/shellchat/locales/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,12 @@
"fr": "",
"ja": "",
"zh": ""
},
"shellchat.bootwait": {
"en": "Please wait...",
"en-tts": "Please wait...",
"fr": "S'il vous plaît, attendez*MT*",
"ja": "お待ちください...",
"zh": "请稍等..."
}
}
82 changes: 75 additions & 7 deletions services/shellchat/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@ Check for more detailed docs under Modules/cmds "Shell Chat" below
use log::info;

use core::fmt::Write;
use core::sync::atomic::{AtomicBool, Ordering};

use gam::UxRegistration;
use graphics_server::{Gid, Point, Rectangle, TextBounds, TextView, DrawStyle, PixelColor};
use graphics_server::api::GlyphStyle;
use xous::MessageEnvelope;
use xous_ipc::Buffer;

use locales::t;
use std::thread;
use std::sync::Arc;

#[doc = include_str!("../README.md")]
mod cmds;
use cmds::*;
Expand Down Expand Up @@ -202,7 +207,7 @@ impl Repl{
}

/// update the loop, in response to various inputs
fn update(&mut self, was_callback: bool) -> Result<(), xous::Error> {
fn update(&mut self, was_callback: bool, init_done: bool) -> Result<(), xous::Error> {
let debug1 = false;
// if we had an input string, do something
if let Some(local) = &self.input {
Expand All @@ -219,7 +224,7 @@ impl Repl{

// redraw UI once upon accepting all input
if !was_callback { // don't need to redraw on a callback, save some cycles
self.redraw().expect("can't redraw");
self.redraw(init_done).expect("can't redraw");
}

let mut dirty = true;
Expand Down Expand Up @@ -265,7 +270,7 @@ impl Repl{
self.msg = None;
// redraw UI now that we've responded
if dirty {
self.redraw().expect("can't redraw");
self.redraw(init_done).expect("can't redraw");
}

if debug1 {
Expand All @@ -286,10 +291,28 @@ impl Repl{
}
)).expect("can't clear content area");
}
fn redraw(&mut self) -> Result<(), xous::Error> {
fn redraw(&mut self, init_done: bool) -> Result<(), xous::Error> {
log::trace!("going into redraw");
self.clear_area();

if !init_done {
let mut init_tv = TextView::new(
self.content,
TextBounds::CenteredTop(
Rectangle::new(
Point::new(0, self.screensize.y / 3 - 64),
Point::new(self.screensize.x, self.screensize.y / 3)
)
)
);
init_tv.style = GlyphStyle::Bold;
init_tv.draw_border = false;
write!(init_tv.text, "{}", t!("shellchat.bootwait", xous::LANG)).ok();
self.gam.post_textview(&mut init_tv).expect("couldn't render wait text");
self.gam.redraw().expect("couldn't redraw screen");
return Ok(())
}

// this defines the bottom border of the text bubbles as they stack up wards
let mut bubble_baseline = self.screensize.y - self.margin.y;

Expand Down Expand Up @@ -393,8 +416,53 @@ fn wrapped_main() -> ! {
let mut was_callback = false;

let mut allow_redraw = true;
log::trace!("starting main loop");
let pddb_init_done = Arc::new(AtomicBool::new(false));

// spawn a thread to auto-mount the PDDB. It's important that this spawn happens after
// our GAM context has been registered (which happened in the `Repl::new()` call above)
repl.redraw(false).ok();
let _ = thread::spawn({
let pddb_init_done = pddb_init_done.clone();
let main_conn = xous::connect(shch_sid).unwrap();
move || {
let tt = ticktimer_server::Ticktimer::new().unwrap();
tt.sleep_ms(500).ok(); // give some time for the system to finish booting
loop {
let (no_retry_failure, count) = pddb::Pddb::new().try_mount();
pddb_init_done.store(true, Ordering::SeqCst);
if no_retry_failure {
// this includes both successfully mounted, and user abort of mount attempt
break;
} else {
// this indicates system was guttered due to a retry failure
let xns = xous_names::XousNames::new().unwrap();
let susres = susres::Susres::new_without_hook(&xns).unwrap();
let llio = llio::Llio::new(&xns);
if ((llio.adc_vbus().unwrap() as u32) * 503) < 150_000 {
// try to force suspend if possible, so that users who are just playing around with
// the device don't run the battery down accidentally.
susres.initiate_suspend().ok();
tt.sleep_ms(1000).unwrap();
let modals = modals::Modals::new(&xns).unwrap();
modals.show_notification(
&t!("login.fail", xous::LANG).replace("{fails}", &count.to_string()),
None
).ok();
} else {
// otherwise force a reboot cycle to slow down guessers
susres.reboot(true).expect("Couldn't reboot after too many failed password attempts");
tt.sleep_ms(5000).unwrap();
}
}
}
tt.sleep_ms(100).ok(); // this allows the shellchat context to foreground before calling the redraw
xous::send_message(main_conn,
xous::Message::new_scalar(ShellOpcode::Redraw.to_usize().unwrap(), 0, 0, 0, 0)
).ok();
}
});

log::trace!("starting main loop");
#[cfg(feature = "autobasis-ci")]
{
log::info!("starting autobasis CI launcher");
Expand All @@ -420,7 +488,7 @@ fn wrapped_main() -> ! {
}
Some(ShellOpcode::Redraw) => {
if allow_redraw {
repl.redraw().expect("REPL couldn't redraw");
repl.redraw(pddb_init_done.load(Ordering::SeqCst)).expect("REPL couldn't redraw");
}
}
Some(ShellOpcode::ChangeFocus) => xous::msg_scalar_unpack!(msg, new_state_code, _, _, _, {
Expand All @@ -446,7 +514,7 @@ fn wrapped_main() -> ! {
}
}
if update_repl {
repl.update(was_callback).expect("REPL had problems updating");
repl.update(was_callback, pddb_init_done.load(Ordering::SeqCst)).expect("REPL had problems updating");
update_repl = false;
}
log::trace!("reached bottom of main loop");
Expand Down

0 comments on commit a56b8c8

Please sign in to comment.