1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

refactor(core): move confirm_homescreen

- this commit does not compile for mercury
This commit is contained in:
obrusvit 2024-10-30 17:25:51 +01:00
parent 634d30b165
commit 765507b9e3
13 changed files with 132 additions and 166 deletions

View File

@ -1,15 +1,12 @@
use crate::{ use crate::{
micropython::{ io::BinaryData, micropython::{
macros::{obj_fn_1, obj_fn_kw, obj_module}, macros::{obj_fn_1, obj_fn_kw, obj_module},
map::Map, map::Map,
module::Module, module::Module,
obj::Obj, obj::Obj,
qstr::Qstr, qstr::Qstr,
util, util,
}, }, strutil::TString, trezorhal::model, ui::{
strutil::TString,
trezorhal::model,
ui::{
backlight::BACKLIGHT_LEVELS_OBJ, backlight::BACKLIGHT_LEVELS_OBJ,
layout::{ layout::{
base::LAYOUT_STATE, base::LAYOUT_STATE,
@ -19,7 +16,7 @@ use crate::{
}, },
ui_features::ModelUI, ui_features::ModelUI,
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
}, }
}; };
// free-standing functions exported to MicroPython mirror `trait // free-standing functions exported to MicroPython mirror `trait
@ -86,6 +83,20 @@ extern "C" fn new_confirm_firmware_update(
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_confirm_homescreen(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()?;
let image: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
let jpeg: BinaryData = image.try_into()?;
let layout = ModelUI::confirm_homescreen(title, jpeg)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_request_bip39(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?; let prompt: TString = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
@ -352,6 +363,14 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Ask whether to update firmware, optionally show fingerprint.""" /// """Ask whether to update firmware, optionally show fingerprint."""
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(), Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
/// def confirm_homescreen(
/// *,
/// title: str,
/// image: bytes,
/// ) -> LayoutObj[UiResult]:
/// """Confirm homescreen."""
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
/// def request_bip39( /// def request_bip39(
/// *, /// *,
/// prompt: str, /// prompt: str,

View File

@ -389,58 +389,6 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_confirm_homescreen(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()?;
let image: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
let jpeg: BinaryData = image.try_into()?;
let obj = if jpeg.is_empty() {
// Incoming data may be empty, meaning we should
// display default homescreen message.
let paragraphs = ParagraphVecShort::from_iter([Paragraph::new(
&theme::TEXT_DEMIBOLD,
TR::homescreen__set_default,
)])
.into_paragraphs();
new_confirm_action_simple(
paragraphs,
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(
TR::homescreen__settings_title.into(),
Some(TR::homescreen__settings_subtitle.into()),
None,
Some(TR::homescreen__settings_title.into()),
),
false,
None,
)
.and_then(LayoutObj::new_root)
.map(Into::into)
} else {
if !check_homescreen_format(jpeg) {
return Err(value_error!(c"Invalid image."));
};
let obj = LayoutObj::new(SwipeUpScreen::new(
Frame::left_aligned(title, SwipeContent::new(CachedJpeg::new(jpeg, 1)))
.with_cancel_button()
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::buttons__change.into()),
)
.with_swipe(Direction::Up, SwipeSettings::default()),
));
Ok(obj?.into())
};
obj
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_reset(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_reset(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let recovery: bool = kwargs.get(Qstr::MP_QSTR_recovery)?.try_into()?; let recovery: bool = kwargs.get(Qstr::MP_QSTR_recovery)?.try_into()?;
@ -1319,14 +1267,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// the first component is a bool indicating whether this part is emphasized.""" /// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
/// def confirm_homescreen(
/// *,
/// title: str,
/// image: bytes,
/// ) -> LayoutObj[UiResult]:
/// """Confirm homescreen."""
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
/// def confirm_blob( /// def confirm_blob(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
error::Error, error::{value_error, Error},
io::BinaryData, io::BinaryData,
micropython::gc::Gc, micropython::gc::Gc,
strutil::TString, strutil::TString,
@ -7,7 +7,8 @@ use crate::{
ui::{ ui::{
component::{ component::{
swipe_detect::SwipeSettings, swipe_detect::SwipeSettings,
text::paragraphs::{Paragraph, Paragraphs}, text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs},
CachedJpeg,
}, },
geometry::Direction, geometry::Direction,
layout::{ layout::{
@ -20,10 +21,11 @@ use crate::{
use super::{ use super::{
component::{ component::{
Bip39Input, Frame, Homescreen, Lockscreen, MnemonicKeyboard, PinKeyboard, SelectWordCount, check_homescreen_format, Bip39Input, Frame, Homescreen, Lockscreen, MnemonicKeyboard,
Slip39Input, SwipeContent, SwipeUpScreen, VerticalMenu, PinKeyboard, SelectWordCount, Slip39Input, SwipeContent, SwipeUpScreen, VerticalMenu,
}, },
flow, theme, ModelMercuryFeatures, flow::{self, new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings},
theme, ModelMercuryFeatures,
}; };
impl UIFeaturesFirmware for ModelMercuryFeatures { impl UIFeaturesFirmware for ModelMercuryFeatures {
@ -54,6 +56,51 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
Ok(flow) Ok(flow)
} }
fn confirm_homescreen(
title: TString<'static>,
image: BinaryData<'static>,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = if image.is_empty() {
// Incoming data may be empty, meaning we should
// display default homescreen message.
let paragraphs = ParagraphVecShort::from_iter([Paragraph::new(
&theme::TEXT_DEMIBOLD,
TR::homescreen__set_default,
)])
.into_paragraphs();
let paragraphs = paragraphs;
new_confirm_action_simple(
paragraphs,
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(
TR::homescreen__settings_title.into(),
Some(TR::homescreen__settings_subtitle.into()),
None,
Some(TR::homescreen__settings_title.into()),
),
false,
None,
)?
} else {
if !check_homescreen_format(image) {
return Err(value_error!(c"Invalid image."));
};
let obj = RootComponent::new(SwipeUpScreen::new(
Frame::left_aligned(title, SwipeContent::new(CachedJpeg::new(image, 1)))
.with_cancel_button()
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::buttons__change.into()),
)
.with_swipe(Direction::Up, SwipeSettings::default()),
));
obj
};
Ok(layout)
}
fn confirm_firmware_update( fn confirm_firmware_update(
description: TString<'static>, description: TString<'static>,
fingerprint: TString<'static>, fingerprint: TString<'static>,

View File

@ -372,17 +372,6 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_confirm_homescreen(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()?;
let image: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
let obj = LayoutObj::new(ConfirmHomescreen::new(title, image.try_into()?))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
@ -1399,14 +1388,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// ///
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(), Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
/// def confirm_homescreen(
/// *,
/// title: str,
/// image: bytes,
/// ) -> object:
/// """Confirm homescreen."""
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
/// def confirm_blob( /// def confirm_blob(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -20,8 +20,8 @@ use crate::{
use super::{ use super::{
component::{ component::{
ButtonDetails, ButtonPage, Frame, Homescreen, Lockscreen, PassphraseEntry, PinEntry, ButtonDetails, ButtonPage, ConfirmHomescreen, Frame, Homescreen, Lockscreen,
ScrollableFrame, SimpleChoice, WordlistEntry, WordlistType, PassphraseEntry, PinEntry, ScrollableFrame, SimpleChoice, WordlistEntry, WordlistType,
}, },
theme, ModelTRFeatures, theme, ModelTRFeatures,
}; };
@ -67,6 +67,14 @@ impl UIFeaturesFirmware for ModelTRFeatures {
) )
} }
fn confirm_homescreen(
title: TString<'static>,
image: BinaryData<'static>,
) -> Result<impl LayoutMaybeTrace, Error> {
let layout = RootComponent::new(ConfirmHomescreen::new(title, image));
Ok(layout)
}
fn confirm_firmware_update( fn confirm_firmware_update(
description: TString<'static>, description: TString<'static>,
fingerprint: TString<'static>, fingerprint: TString<'static>,

View File

@ -565,35 +565,6 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_confirm_homescreen(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()?;
let image: Obj = kwargs.get(Qstr::MP_QSTR_image)?;
let mut jpeg: BinaryData = image.try_into()?;
if jpeg.is_empty() {
// Incoming data may be empty, meaning we should
// display default homescreen image.
jpeg = theme::IMAGE_HOMESCREEN.into();
}
if !check_homescreen_format(jpeg, false) {
return Err(value_error!(c"Invalid image."));
};
let buttons = Button::cancel_confirm_text(None, Some(TR::buttons__change.into()));
let obj = LayoutObj::new(Frame::centered(
theme::label_title(),
title,
Dialog::new(Jpeg::new(jpeg, 1), buttons),
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
@ -1417,14 +1388,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// the first component is a bool indicating whether this part is emphasized.""" /// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
/// def confirm_homescreen(
/// *,
/// title: str,
/// image: bytes,
/// ) -> LayoutObj[UiResult]:
/// """Confirm homescreen."""
Qstr::MP_QSTR_confirm_homescreen => obj_fn_kw!(0, new_confirm_homescreen).as_obj(),
/// def confirm_blob( /// def confirm_blob(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -1,14 +1,12 @@
use crate::{ use crate::{
error::Error, error::{value_error, Error},
io::BinaryData, io::BinaryData,
micropython::gc::Gc, micropython::gc::Gc,
strutil::TString, strutil::TString,
translations::TR, translations::TR,
ui::{ ui::{
component::{ component::{
image::BlendedImage, image::BlendedImage, text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt}, ComponentExt, Empty, Jpeg, Label, Timeout
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt},
ComponentExt, Empty, Label, Timeout,
}, },
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
@ -20,9 +18,9 @@ use crate::{
use super::{ use super::{
component::{ component::{
Bip39Input, Button, ButtonMsg, ButtonPage, ButtonStyleSheet, CancelConfirmMsg, Dialog, check_homescreen_format, Bip39Input, Button, ButtonMsg, ButtonPage, ButtonStyleSheet,
Frame, Homescreen, IconDialog, Lockscreen, MnemonicKeyboard, PassphraseKeyboard, CancelConfirmMsg, Dialog, Frame, Homescreen, IconDialog, Lockscreen, MnemonicKeyboard,
PinKeyboard, SelectWordCount, Slip39Input, PassphraseKeyboard, PinKeyboard, SelectWordCount, Slip39Input,
}, },
theme, ModelTTFeatures, theme, ModelTTFeatures,
}; };
@ -69,6 +67,29 @@ impl UIFeaturesFirmware for ModelTTFeatures {
Ok(layout) Ok(layout)
} }
fn confirm_homescreen(
title: TString<'static>,
mut image: BinaryData<'static>,
) -> Result<impl LayoutMaybeTrace, Error> {
if image.is_empty() {
// Incoming data may be empty, meaning we should
// display default homescreen image.
image = theme::IMAGE_HOMESCREEN.into();
}
if !check_homescreen_format(image, false) {
return Err(value_error!(c"Invalid image."));
};
let buttons = Button::cancel_confirm_text(None, Some(TR::buttons__change.into()));
let layout = RootComponent::new(Frame::centered(
theme::label_title(),
title,
Dialog::new(Jpeg::new(image, 1), buttons),
));
Ok(layout)
}
fn confirm_firmware_update( fn confirm_firmware_update(
description: TString<'static>, description: TString<'static>,
fingerprint: TString<'static>, fingerprint: TString<'static>,

View File

@ -20,6 +20,11 @@ pub trait UIFeaturesFirmware {
prompt_title: Option<TString<'static>>, prompt_title: Option<TString<'static>>,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_homescreen(
title: TString<'static>,
image: BinaryData<'static>,
) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_firmware_update( fn confirm_firmware_update(
description: TString<'static>, description: TString<'static>,
fingerprint: TString<'static>, fingerprint: TString<'static>,

View File

@ -14,15 +14,6 @@ def confirm_emphasized(
the first component is a bool indicating whether this part is emphasized.""" the first component is a bool indicating whether this part is emphasized."""
# rust/src/ui/model_mercury/layout.rs
def confirm_homescreen(
*,
title: str,
image: bytes,
) -> LayoutObj[UiResult]:
"""Confirm homescreen."""
# rust/src/ui/model_mercury/layout.rs # rust/src/ui/model_mercury/layout.rs
def confirm_blob( def confirm_blob(
*, *,
@ -424,15 +415,6 @@ from trezor import utils
from trezorui_api import * from trezorui_api import *
# rust/src/ui/model_tr/layout.rs
def confirm_homescreen(
*,
title: str,
image: bytes,
) -> object:
"""Confirm homescreen."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def confirm_blob( def confirm_blob(
*, *,
@ -771,15 +753,6 @@ def confirm_emphasized(
the first component is a bool indicating whether this part is emphasized.""" the first component is a bool indicating whether this part is emphasized."""
# rust/src/ui/model_tt/layout.rs
def confirm_homescreen(
*,
title: str,
image: bytes,
) -> LayoutObj[UiResult]:
"""Confirm homescreen."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def confirm_blob( def confirm_blob(
*, *,

View File

@ -105,6 +105,15 @@ def confirm_firmware_update(
"""Ask whether to update firmware, optionally show fingerprint.""" """Ask whether to update firmware, optionally show fingerprint."""
# rust/src/ui/api/firmware_upy.rs
def confirm_homescreen(
*,
title: str,
image: bytes,
) -> LayoutObj[UiResult]:
"""Confirm homescreen."""
# rust/src/ui/api/firmware_upy.rs # rust/src/ui/api/firmware_upy.rs
def request_bip39( def request_bip39(
*, *,

View File

@ -149,7 +149,7 @@ def confirm_homescreen(
workflow.close_others() workflow.close_others()
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_homescreen( trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set, title=TR.homescreen__title_set,
image=image, image=image,
), ),

View File

@ -184,7 +184,7 @@ def confirm_multisig_warning() -> Awaitable[ui.UiResult]:
def confirm_homescreen(image: bytes) -> Awaitable[None]: def confirm_homescreen(image: bytes) -> Awaitable[None]:
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_homescreen( trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set, title=TR.homescreen__title_set,
image=image, image=image,
), ),

View File

@ -165,7 +165,7 @@ def confirm_multisig_warning() -> Awaitable[None]:
def confirm_homescreen(image: bytes) -> Awaitable[None]: def confirm_homescreen(image: bytes) -> Awaitable[None]:
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_homescreen( trezorui_api.confirm_homescreen(
title=TR.homescreen__title_set, title=TR.homescreen__title_set,
image=image, image=image,
), ),