diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 1f5384b583..a4314fa45e 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -195,6 +195,7 @@ static void _librust_qstrs(void) { MP_QSTR_case_sensitive; MP_QSTR_check_homescreen_format; MP_QSTR_chunkify; + MP_QSTR_code; MP_QSTR_coinjoin__access_account; MP_QSTR_coinjoin__do_not_disconnect; MP_QSTR_coinjoin__max_mining_fee; @@ -237,6 +238,7 @@ static void _librust_qstrs(void) { MP_QSTR_deinit; MP_QSTR_description; MP_QSTR_details_title; + MP_QSTR_device_name; MP_QSTR_device_name__change_template; MP_QSTR_device_name__title; MP_QSTR_disable_animation; @@ -669,6 +671,8 @@ static void _librust_qstrs(void) { MP_QSTR_show_instructions; MP_QSTR_show_lockscreen; MP_QSTR_show_mismatch; + MP_QSTR_show_pairing_code; + MP_QSTR_show_pairing_device_name; MP_QSTR_show_progress; MP_QSTR_show_progress_coinjoin; MP_QSTR_show_remaining_shares; diff --git a/core/embed/rust/src/ui/api/firmware_micropython.rs b/core/embed/rust/src/ui/api/firmware_micropython.rs index c5d672fb16..c54f959c36 100644 --- a/core/embed/rust/src/ui/api/firmware_micropython.rs +++ b/core/embed/rust/src/ui/api/firmware_micropython.rs @@ -815,6 +815,30 @@ extern "C" fn new_show_device_menu(n_args: usize, args: *const Obj, kwargs: *mut unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } +extern "C" fn new_show_pairing_device_name( + n_args: usize, + args: *const Obj, + kwargs: *mut Map, +) -> Obj { + let block = move |_args: &[Obj], kwargs: &Map| { + let device_name: TString = kwargs.get(Qstr::MP_QSTR_device_name)?.try_into()?; + let layout = ModelUI::show_pairing_device_name(device_name)?; + let layout_obj = LayoutObj::new_root(layout)?; + Ok(layout_obj.into()) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } +} + +extern "C" fn new_show_pairing_code(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { + let block = move |_args: &[Obj], kwargs: &Map| { + let code: TString = kwargs.get(Qstr::MP_QSTR_code)?.try_into()?; + let layout = ModelUI::show_pairing_code(code)?; + let layout_obj = LayoutObj::new_root(layout)?; + Ok(layout_obj.into()) + }; + unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } +} + extern "C" fn new_show_info(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()?; @@ -1583,6 +1607,20 @@ pub static mp_module_trezorui_api: Module = obj_module! { /// """Show the device menu.""" Qstr::MP_QSTR_show_device_menu => obj_fn_kw!(0, new_show_device_menu).as_obj(), + /// def show_pairing_device_name( + /// *, + /// device_name: str, + /// ) -> LayoutObj[UiResult]: + /// """Pairing device: first screen (device name).""" + Qstr::MP_QSTR_show_pairing_device_name => obj_fn_kw!(0, new_show_pairing_device_name).as_obj(), + + /// def show_pairing_code( + /// *, + /// code: str, + /// ) -> LayoutObj[UiResult]: + /// """Pairing device: second screen (pairing code).""" + Qstr::MP_QSTR_show_pairing_code => obj_fn_kw!(0, new_show_pairing_code).as_obj(), + /// def show_info( /// *, /// title: str, diff --git a/core/embed/rust/src/ui/layout_bolt/ui_firmware.rs b/core/embed/rust/src/ui/layout_bolt/ui_firmware.rs index 262dd1c48e..178ab6a53f 100644 --- a/core/embed/rust/src/ui/layout_bolt/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_bolt/ui_firmware.rs @@ -880,6 +880,20 @@ impl FirmwareUI for UIBolt { )) } + fn show_pairing_device_name( + _device_name: TString<'static>, + ) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_device_name not supported", + )) + } + + fn show_pairing_code(_code: TString<'static>) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_code not supported", + )) + } + fn show_info( title: TString<'static>, description: TString<'static>, diff --git a/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs b/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs index 0fd5be7b42..31cf918552 100644 --- a/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_caesar/ui_firmware.rs @@ -1046,6 +1046,20 @@ impl FirmwareUI for UICaesar { )) } + fn show_pairing_device_name( + _device_name: TString<'static>, + ) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_device_name not supported", + )) + } + + fn show_pairing_code(_code: TString<'static>) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_code not supported", + )) + } + fn show_info( title: TString<'static>, description: TString<'static>, diff --git a/core/embed/rust/src/ui/layout_delizia/ui_firmware.rs b/core/embed/rust/src/ui/layout_delizia/ui_firmware.rs index 89ec90a9a9..5907fec858 100644 --- a/core/embed/rust/src/ui/layout_delizia/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_delizia/ui_firmware.rs @@ -898,6 +898,20 @@ impl FirmwareUI for UIDelizia { )) } + fn show_pairing_device_name( + _device_name: TString<'static>, + ) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_device_name not supported", + )) + } + + fn show_pairing_code(_code: TString<'static>) -> Result { + Err::, Error>(Error::ValueError( + c"show_pairing_code not supported", + )) + } + fn show_info( title: TString<'static>, description: TString<'static>, diff --git a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs index 608903acfe..fea918db14 100644 --- a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs @@ -17,7 +17,7 @@ use crate::{ }, Empty, FormattedText, }, - geometry::{LinearPlacement, Offset}, + geometry::{Alignment, LinearPlacement, Offset}, layout::{ obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, util::{ConfirmValueParams, RecoveryType, StrOrBytes}, @@ -796,6 +796,40 @@ impl FirmwareUI for UIEckhart { Ok(layout) } + fn show_pairing_device_name( + device_name: TString<'static>, + ) -> Result { + let font = fonts::FONT_SATOSHI_REGULAR_38; + let text_style = theme::firmware::TEXT_REGULAR; + let mut ops = OpTextLayout::new(text_style); + ops = ops.color(theme::GREEN); + ops = ops.text(device_name, font); + ops = ops.color(text_style.text_color); + let text: TString = " is your Trezor's name.".into(); + ops = ops.text(text, font); + let screen = TextScreen::new(FormattedText::new(ops)) + .with_header(Header::new("Pair with new device".into()).with_close_button()) + .with_action_bar(ActionBar::new_single(Button::with_text( + "Continue on host".into(), + ))); + let layout = RootComponent::new(screen); + Ok(layout) + } + + fn show_pairing_code(code: TString<'static>) -> Result { + let text: TString<'static> = "Pairing code match?".into(); + let mut ops = OpTextLayout::new(theme::firmware::TEXT_REGULAR); + ops = ops.text(text, fonts::FONT_SATOSHI_REGULAR_38); + ops = ops.newline().newline().newline(); + ops = ops.alignment(Alignment::Center); + ops = ops.text(code, fonts::FONT_SATOSHI_EXTRALIGHT_72); + let screen = TextScreen::new(FormattedText::new(ops)) + .with_header(Header::new("Bluetooth pairing".into())) + .with_action_bar(ActionBar::new_cancel_confirm()); + let layout = RootComponent::new(screen); + Ok(layout) + } + fn show_info( title: TString<'static>, description: TString<'static>, diff --git a/core/embed/rust/src/ui/ui_firmware.rs b/core/embed/rust/src/ui/ui_firmware.rs index 7253ea8e7c..cb3c8e1dc4 100644 --- a/core/embed/rust/src/ui/ui_firmware.rs +++ b/core/embed/rust/src/ui/ui_firmware.rs @@ -307,6 +307,12 @@ pub trait FirmwareUI { paired_devices: Vec, 1>, ) -> Result; + fn show_pairing_device_name( + device_name: TString<'static>, + ) -> Result; + + fn show_pairing_code(code: TString<'static>) -> Result; + fn show_info( title: TString<'static>, description: TString<'static>, diff --git a/core/mocks/generated/trezorui_api.pyi b/core/mocks/generated/trezorui_api.pyi index 9d6e098e9a..38994d6c62 100644 --- a/core/mocks/generated/trezorui_api.pyi +++ b/core/mocks/generated/trezorui_api.pyi @@ -542,6 +542,22 @@ def show_device_menu( """Show the device menu.""" +# rust/src/ui/api/firmware_micropython.rs +def show_pairing_device_name( + *, + device_name: str, +) -> LayoutObj[UiResult]: + """Pairing device: first screen (device name).""" + + +# rust/src/ui/api/firmware_micropython.rs +def show_pairing_code( + *, + code: str, +) -> LayoutObj[UiResult]: + """Pairing device: second screen (pairing code).""" + + # rust/src/ui/api/firmware_micropython.rs def show_info( *,