mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-19 12:58:13 +00:00
feat(core/mercury): change FW update UI
This commit changes the UI of confirming interaction-less firmware update.
This commit is contained in:
parent
53799cdee8
commit
f41176af02
1
core/.changelog.d/4030.added
Normal file
1
core/.changelog.d/4030.added
Normal file
@ -0,0 +1 @@
|
||||
[T3T1] New UI of confirming interaction-less firmware update
|
@ -0,0 +1,144 @@
|
||||
use crate::{
|
||||
error,
|
||||
micropython::{map::Map, obj::Obj, qstr::Qstr, util},
|
||||
strutil::TString,
|
||||
translations::TR,
|
||||
ui::{
|
||||
component::{
|
||||
swipe_detect::SwipeSettings,
|
||||
text::paragraphs::{Paragraph, Paragraphs},
|
||||
ComponentExt, SwipeDirection,
|
||||
},
|
||||
flow::{
|
||||
base::{DecisionBuilder as _, StateChange},
|
||||
FlowMsg, FlowState, SwipeFlow,
|
||||
},
|
||||
layout::obj::LayoutObj,
|
||||
},
|
||||
};
|
||||
|
||||
use super::super::{
|
||||
component::{
|
||||
CancelInfoConfirmMsg, Frame, FrameMsg, PromptScreen, SwipeContent, VerticalMenu,
|
||||
VerticalMenuChoiceMsg,
|
||||
},
|
||||
theme,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ConfirmFirmwareUpdate {
|
||||
Intro,
|
||||
Menu,
|
||||
Fingerprint,
|
||||
Confirm,
|
||||
}
|
||||
|
||||
impl FlowState for ConfirmFirmwareUpdate {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
|
||||
match (self, direction) {
|
||||
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
|
||||
(Self::Intro, SwipeDirection::Up) => Self::Confirm.swipe(direction),
|
||||
(Self::Menu, SwipeDirection::Right) => Self::Intro.swipe(direction),
|
||||
(Self::Fingerprint, SwipeDirection::Right) => Self::Menu.swipe(direction),
|
||||
(Self::Confirm, SwipeDirection::Down) => Self::Intro.swipe(direction),
|
||||
(Self::Confirm, SwipeDirection::Left) => Self::Menu.swipe(direction),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
|
||||
match (self, msg) {
|
||||
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => Self::Fingerprint.transit(),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::Fingerprint, FlowMsg::Cancelled) => Self::Menu.transit(),
|
||||
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
pub extern "C" fn new_confirm_firmware_update(
|
||||
n_args: usize,
|
||||
args: *const Obj,
|
||||
kwargs: *mut Map,
|
||||
) -> Obj {
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, ConfirmFirmwareUpdate::new_obj) }
|
||||
}
|
||||
|
||||
impl ConfirmFirmwareUpdate {
|
||||
fn new_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> {
|
||||
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let fingerprint: TString = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
|
||||
|
||||
let paragraphs = Paragraphs::new(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, description));
|
||||
let content_intro = Frame::left_aligned(
|
||||
TR::firmware_update__title.into(),
|
||||
SwipeContent::new(paragraphs),
|
||||
)
|
||||
.with_menu_button()
|
||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
|
||||
.with_swipe(SwipeDirection::Left, SwipeSettings::default())
|
||||
.map(|msg| {
|
||||
matches!(msg, FrameMsg::Button(CancelInfoConfirmMsg::Info)).then_some(FlowMsg::Info)
|
||||
});
|
||||
|
||||
let content_menu = Frame::left_aligned(
|
||||
TString::empty(),
|
||||
VerticalMenu::empty()
|
||||
.item(
|
||||
theme::ICON_CHEVRON_RIGHT,
|
||||
TR::firmware_update__title_fingerprint.into(),
|
||||
)
|
||||
.danger(theme::ICON_CANCEL, TR::buttons__cancel.into()),
|
||||
)
|
||||
.with_cancel_button()
|
||||
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
|
||||
.map(|msg| match msg {
|
||||
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
|
||||
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
|
||||
});
|
||||
|
||||
let paragraphs_fingerprint =
|
||||
Paragraphs::new(Paragraph::new(&theme::TEXT_MONO_GREY_LIGHT, fingerprint));
|
||||
let content_fingerprint = Frame::left_aligned(
|
||||
TR::firmware_update__title_fingerprint.into(),
|
||||
SwipeContent::new(paragraphs_fingerprint),
|
||||
)
|
||||
.with_cancel_button()
|
||||
.with_swipe(SwipeDirection::Right, SwipeSettings::default())
|
||||
.map(|msg| {
|
||||
matches!(msg, FrameMsg::Button(CancelInfoConfirmMsg::Cancelled))
|
||||
.then_some(FlowMsg::Cancelled)
|
||||
});
|
||||
|
||||
let content_confirm = Frame::left_aligned(
|
||||
TR::firmware_update__title.into(),
|
||||
SwipeContent::new(PromptScreen::new_hold_to_confirm()),
|
||||
)
|
||||
.with_menu_button()
|
||||
.with_footer(TR::instructions__hold_to_confirm.into(), None)
|
||||
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
|
||||
.with_swipe(SwipeDirection::Left, SwipeSettings::default())
|
||||
.map(|msg| match msg {
|
||||
FrameMsg::Content(()) => Some(FlowMsg::Confirmed),
|
||||
FrameMsg::Button(_) => Some(FlowMsg::Info),
|
||||
});
|
||||
|
||||
let res = SwipeFlow::new(&ConfirmFirmwareUpdate::Intro)?
|
||||
.with_page(&ConfirmFirmwareUpdate::Intro, content_intro)?
|
||||
.with_page(&ConfirmFirmwareUpdate::Menu, content_menu)?
|
||||
.with_page(&ConfirmFirmwareUpdate::Fingerprint, content_fingerprint)?
|
||||
.with_page(&ConfirmFirmwareUpdate::Confirm, content_confirm)?;
|
||||
Ok(LayoutObj::new(res)?.into())
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod confirm_action;
|
||||
pub mod confirm_firmware_update;
|
||||
pub mod confirm_output;
|
||||
pub mod confirm_reset_create;
|
||||
pub mod confirm_reset_recover;
|
||||
@ -15,6 +16,7 @@ pub mod warning_hi_prio;
|
||||
pub use confirm_action::{new_confirm_action, new_confirm_action_simple};
|
||||
mod util;
|
||||
|
||||
pub use confirm_firmware_update::new_confirm_firmware_update;
|
||||
pub use confirm_output::new_confirm_output;
|
||||
pub use confirm_reset_create::ConfirmResetCreate;
|
||||
pub use confirm_reset_recover::ConfirmResetRecover;
|
||||
|
@ -42,7 +42,7 @@ use crate::{
|
||||
},
|
||||
TextStyle,
|
||||
},
|
||||
Border, CachedJpeg, Component, FormattedText, Label, Never, SwipeDirection, Timeout,
|
||||
Border, CachedJpeg, Component, FormattedText, Never, SwipeDirection, Timeout,
|
||||
},
|
||||
flow::Swipable,
|
||||
geometry,
|
||||
@ -266,15 +266,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
super::component::bl_confirm::ConfirmMsg::Cancel => Ok(CANCELLED.as_obj()),
|
||||
super::component::bl_confirm::ConfirmMsg::Confirm => Ok(CONFIRMED.as_obj()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
@ -1250,36 +1241,6 @@ pub extern "C" fn upy_check_homescreen_format(data: Obj) -> Obj {
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn new_confirm_firmware_update(
|
||||
n_args: usize,
|
||||
args: *const Obj,
|
||||
kwargs: *mut Map,
|
||||
) -> Obj {
|
||||
use super::component::bl_confirm::{Confirm, ConfirmTitle};
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let fingerprint: TString = kwargs.get(Qstr::MP_QSTR_fingerprint)?.try_into()?;
|
||||
|
||||
let title_str = TR::firmware_update__title.into();
|
||||
let title = Label::left_aligned(title_str, theme::TEXT_BOLD).vertically_centered();
|
||||
let msg = Label::left_aligned(description, theme::TEXT_NORMAL);
|
||||
|
||||
let left = Button::with_text(TR::buttons__cancel.into()).styled(theme::button_default());
|
||||
let right = Button::with_text(TR::buttons__install.into()).styled(theme::button_confirm());
|
||||
|
||||
let obj = LayoutObj::new(
|
||||
Confirm::new(theme::BG, left, right, ConfirmTitle::Text(title), msg).with_info(
|
||||
TR::firmware_update__title_fingerprint.into(),
|
||||
fingerprint,
|
||||
theme::button_default(),
|
||||
),
|
||||
)?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_wait_text(message: Obj) -> Obj {
|
||||
let block = || {
|
||||
let message: TString<'static> = message.try_into()?;
|
||||
@ -1811,8 +1772,8 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// description: str,
|
||||
/// fingerprint: str,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
|
||||
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
|
||||
/// """Ask whether to update firmware, optionally show fingerprint."""
|
||||
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, flow::confirm_firmware_update::new_confirm_firmware_update).as_obj(),
|
||||
|
||||
/// def tutorial() -> LayoutObj[UiResult]:
|
||||
/// """Show user how to interact with the device."""
|
||||
|
@ -2044,7 +2044,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// *,
|
||||
/// description: str,
|
||||
/// fingerprint: str,
|
||||
/// ) -> None:
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
|
||||
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
|
||||
|
||||
|
@ -538,7 +538,7 @@ def confirm_firmware_update(
|
||||
description: str,
|
||||
fingerprint: str,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
|
||||
"""Ask whether to update firmware, optionally show fingerprint."""
|
||||
|
||||
|
||||
# rust/src/ui/model_mercury/layout.rs
|
||||
@ -1079,7 +1079,7 @@ def confirm_firmware_update(
|
||||
*,
|
||||
description: str,
|
||||
fingerprint: str,
|
||||
) -> None:
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user