Merge branch 'main' of github.com:betrusted-io/xous-core into main

This commit is contained in:
bunnie 2022-11-17 19:44:05 +08:00
commit 71df3a624b
6 changed files with 113 additions and 3 deletions

View file

@ -115,6 +115,14 @@ impl TextEntryPayload {
}
}
#[derive(Debug, Copy, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct SliderPayload(pub u32);
impl SliderPayload {
pub fn new(value: u32) -> Self {
SliderPayload(value)
}
}
#[derive(Debug, Copy, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct RadioButtonPayload(pub ItemName); // returns the name of the item corresponding to the radio button selection
impl RadioButtonPayload {

View file

@ -47,6 +47,11 @@ impl Slider {
show_legend,
}
}
pub fn set_is_progressbar(&mut self, setting: bool) {
self.is_progressbar = setting;
}
pub fn set_is_password(&mut self, setting: bool) {
// this will cause text to be inverted. Untrusted entities can try to set this,
// but the GAM should defeat this for dialog boxes outside of the trusted boot
@ -194,8 +199,11 @@ impl ActionApi for Slider {
gam.relinquish_focus().unwrap();
xous::yield_slice();
send_message(self.action_conn,
xous::Message::new_scalar(self.action_opcode as usize, self.action_payload as usize, 0, 0, 0)).expect("couldn't pass on action payload");
let ret_payload = SliderPayload(self.action_payload);
let buf = Buffer::into_buf(ret_payload).expect("couldn't convert message to payload");
buf.send(self.action_conn, self.action_opcode).map(|_| ()).expect("couldn't send action message");
return None;
}
_ => {

View file

@ -69,6 +69,8 @@ pub struct ManagedProgress {
pub end_work: u32,
/// current quanta of work. Used to int the bar, updates are just a scalar with the same value.
pub current_work: u32,
/// can user interact with it?
pub user_interaction: bool,
}
/// This isn't a terribly useful notification -- it's basically read-only, no interactivity,
@ -98,6 +100,8 @@ pub(crate) enum Opcode {
Bip39 = 31, // ---- note op number
Bip39Input = 32, // ----- note op number
Bip39Return = 33, // ----- note op number
SliderReturn = 34,
Slider = 35,
/// display an image
#[cfg(feature = "ditherpunk")]
Image = 3,

View file

@ -302,6 +302,7 @@ impl Modals {
start_work: start,
end_work: end,
current_work: current,
user_interaction: false,
};
let buf = Buffer::into_buf(spec).or(Err(xous::Error::InternalError))?;
buf.lend(self.conn, Opcode::StartProgress.to_u32().unwrap())
@ -309,6 +310,32 @@ impl Modals {
Ok(())
}
pub fn slider(
&self,
title: &str,
start: u32,
end: u32,
current: u32,
) -> Result<u32, xous::Error> {
self.lock();
let spec = ManagedProgress {
token: self.token,
title: xous_ipc::String::from_str(title),
start_work: start,
end_work: end,
current_work: current,
user_interaction: true,
};
let mut buf = Buffer::into_buf(spec).or(Err(xous::Error::InternalError))?;
buf.lend_mut(self.conn, Opcode::Slider.to_u32().unwrap())
.or(Err(xous::Error::InternalError))?;
let orig = buf.to_original::<SliderPayload, _>().unwrap();
self.unlock();
Ok(orig.0)
}
/// note that this API is not atomically token-locked, so, someone could mess with the progress bar state
/// but, progress updates are meant to be fast and frequent, and generally if a progress bar shows
/// something whacky it's not going to affect a security outcome

View file

@ -113,7 +113,7 @@ fn wrapped_main() -> ! {
let mut fixed_items = Vec::<ItemName>::new();
let mut progress_action = Slider::new(
renderer_cid,
Opcode::Gutter.to_u32().unwrap(),
Opcode::SliderReturn.to_u32().unwrap(),
0,
100,
1,
@ -332,6 +332,24 @@ fn wrapped_main() -> ! {
)
.expect("couldn't initiate UX op");
}
Some(Opcode::Slider) => {
let spec = {
let buffer =
unsafe { Buffer::from_memory_message_mut(msg.body.memory_message_mut().unwrap()) };
buffer.to_original::<ManagedProgress, _>().unwrap()
};
if spec.token != token_lock.unwrap_or(default_nonce) {
log::warn!("Attempt to access modals without a mutex lock. Ignoring.");
continue;
}
op = RendererState::RunProgress(spec);
dr = Some(msg);
send_message(
renderer_cid,
Message::new_scalar(Opcode::InitiateOp.to_usize().unwrap(), 0, 0, 0, 0),
)
.expect("couldn't initiate UX op");
}
Some(Opcode::StopProgress) => msg_blocking_scalar_unpack!(msg, t0, t1, t2, t3, {
let token = [t0 as u32, t1 as u32, t2 as u32, t3 as u32];
if token != token_lock.unwrap_or(default_nonce) {
@ -593,6 +611,7 @@ fn wrapped_main() -> ! {
end_work
);
progress_action.set_state(last_percentage);
progress_action.set_is_progressbar(!config.user_interaction);
#[cfg(feature = "tts")]
tts.tts_simple(config.title.as_str().unwrap()).unwrap();
renderer_modal.modify(
@ -603,6 +622,7 @@ fn wrapped_main() -> ! {
true,
Some(DEFAULT_STYLE),
);
renderer_modal.activate();
}
RendererState::RunRadio(config) => {
@ -764,6 +784,32 @@ fn wrapped_main() -> ! {
xous::return_scalar2(sender, 1, k).unwrap();
}
}),
Some(Opcode::SliderReturn) => match op {
RendererState::RunProgress(_) => {
let buffer =
unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
let item = buffer.to_original::<SliderPayload, _>().unwrap();
if let Some(mut origin) = dr.take() {
let mut response = unsafe {
Buffer::from_memory_message_mut(
origin.body.memory_message_mut().unwrap(),
)
};
response.replace(item).unwrap();
op = RendererState::None;
token_lock = next_lock(&mut work_queue);
} else {
log::error!("Ux routine returned but no origin was recorded");
panic!("Ux routine returned but no origin was recorded");
}
},
_ => {
log::warn!("got weird stuff on slider return, ignoring");
}
},
Some(Opcode::TextEntryReturn) => match op {
RendererState::RunText(_config) => {
log::trace!("validating text entry modal");

View file

@ -96,6 +96,20 @@ pub fn spawn_test() {
}
Err(e) => log::error!("couldn't get input: {:?}", e),
}
// 6. human interaction-enabled slider
log::info!("testing human interaction-enabled slider");
let result = modals.slider(
"Human interaction-enabled slider!",
0,
100,
50,
).expect("slider test failed");
modals.show_notification(&format!("Slider value: {}", result), None)
.expect("cannot show slider result notification");
log::info!("slider test done");
}
});
@ -165,6 +179,9 @@ pub fn spawn_test() {
modals.show_image(bm).expect("show image modal failed");
log::info!("image modal test done");
}
// 6. test that human-interactable slider modal
log::info!("testing human interaction-enabled modal");
}
});
}