mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-18 03:10:58 +00:00
refactor(core/rust): introduce UIFeaturesXXX trait as an abstraction over different UI implementation
[no changelog]
This commit is contained in:
parent
ba741b81fd
commit
535a052df4
@ -1,34 +1,5 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
uint32_t screen_install_confirm(const char* vendor_str, uint8_t vendor_str_len,
|
||||
const char* version_str,
|
||||
const uint8_t* fingerprint,
|
||||
bool should_keep_seed, bool is_newvendor,
|
||||
int version_cmp);
|
||||
uint32_t screen_wipe_confirm(void);
|
||||
void screen_install_progress(int16_t progress, bool initialize,
|
||||
bool initial_setup);
|
||||
void screen_wipe_progress(int16_t progress, bool initialize);
|
||||
uint32_t screen_intro(const char* bld_version_str, const char* vendor_str,
|
||||
uint8_t vendor_str_len, const char* version_str,
|
||||
bool fw_ok);
|
||||
uint32_t screen_menu(secbool firmware_present);
|
||||
void screen_connect(bool initial_setup);
|
||||
void screen_fatal_error_rust(const char* title, const char* msg,
|
||||
const char* footer);
|
||||
void screen_wipe_success(void);
|
||||
void screen_wipe_fail(void);
|
||||
uint32_t screen_install_success(uint8_t restart_seconds, bool initial_setup,
|
||||
bool complete_draw);
|
||||
uint32_t screen_install_fail(void);
|
||||
void screen_welcome(void);
|
||||
void screen_boot_empty(bool fading);
|
||||
void screen_boot_full(void);
|
||||
uint32_t screen_unlock_bootloader_confirm(void);
|
||||
void screen_unlock_bootloader_success(void);
|
||||
void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen);
|
||||
void display_icon(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen,
|
||||
uint16_t fg_color, uint16_t bg_color);
|
||||
void bld_continue_label(uint16_t bg_color);
|
||||
#include "rust_ui_bootloader.h"
|
||||
#include "rust_ui_common.h"
|
||||
|
26
core/embed/rust/rust_ui_bootloader.h
Normal file
26
core/embed/rust/rust_ui_bootloader.h
Normal file
@ -0,0 +1,26 @@
|
||||
#include "common.h"
|
||||
|
||||
uint32_t screen_install_confirm(const char* vendor_str, uint8_t vendor_str_len,
|
||||
const char* version_str,
|
||||
const uint8_t* fingerprint,
|
||||
bool should_keep_seed, bool is_newvendor,
|
||||
int version_cmp);
|
||||
uint32_t screen_wipe_confirm(void);
|
||||
void screen_install_progress(int16_t progress, bool initialize,
|
||||
bool initial_setup);
|
||||
void screen_wipe_progress(int16_t progress, bool initialize);
|
||||
uint32_t screen_intro(const char* bld_version_str, const char* vendor_str,
|
||||
uint8_t vendor_str_len, const char* version_str,
|
||||
bool fw_ok);
|
||||
uint32_t screen_menu(secbool firmware_present);
|
||||
void screen_connect(bool initial_setup);
|
||||
void screen_wipe_success(void);
|
||||
void screen_wipe_fail(void);
|
||||
uint32_t screen_install_success(uint8_t restart_seconds, bool initial_setup,
|
||||
bool complete_draw);
|
||||
uint32_t screen_install_fail(void);
|
||||
void screen_welcome(void);
|
||||
void screen_boot_empty(bool fading);
|
||||
uint32_t screen_unlock_bootloader_confirm(void);
|
||||
void screen_unlock_bootloader_success(void);
|
||||
void bld_continue_label(uint16_t bg_color);
|
10
core/embed/rust/rust_ui_common.h
Normal file
10
core/embed/rust/rust_ui_common.h
Normal file
@ -0,0 +1,10 @@
|
||||
#include "common.h"
|
||||
|
||||
void screen_fatal_error_rust(const char* title, const char* msg,
|
||||
const char* footer);
|
||||
|
||||
void screen_boot_full(void);
|
||||
|
||||
void display_image(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen);
|
||||
void display_icon(int16_t x, int16_t y, const uint8_t* data, uint32_t datalen,
|
||||
uint16_t fg_color, uint16_t bg_color);
|
@ -5,7 +5,7 @@ mod ffi {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::ui::screens::screen_fatal_error;
|
||||
use crate::ui::ui_features::{ModelUI, UIFeaturesCommon};
|
||||
|
||||
fn shutdown() -> ! {
|
||||
unsafe { ffi::trezor_shutdown() }
|
||||
@ -13,13 +13,13 @@ fn shutdown() -> ! {
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
pub fn __fatal_error(_expr: &str, _msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
|
||||
screen_fatal_error("BL.rs", "BL.rs", "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
ModelUI::screen_fatal_error("BL.rs", "BL.rs", "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
shutdown()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bootloader"))]
|
||||
pub fn __fatal_error(_expr: &str, msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
|
||||
screen_fatal_error("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
ModelUI::screen_fatal_error("INTERNAL_ERROR", msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
shutdown()
|
||||
}
|
||||
|
||||
|
127
core/embed/rust/src/ui/api/bootloader_c.rs
Normal file
127
core/embed/rust/src/ui/api/bootloader_c.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use crate::{
|
||||
strutil::hexlify,
|
||||
trezorhal::secbool::secbool,
|
||||
ui::{
|
||||
ui_features::{ModelUI, UIFeaturesBootloader},
|
||||
util::{from_c_array, from_c_str},
|
||||
},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_welcome() {
|
||||
ModelUI::screen_welcome();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn bld_continue_label(bg_color: cty::uint16_t) {
|
||||
ModelUI::bld_continue_label(bg_color.into());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_success(
|
||||
restart_seconds: u8,
|
||||
initial_setup: bool,
|
||||
complete_draw: bool,
|
||||
) {
|
||||
ModelUI::screen_install_success(restart_seconds, initial_setup, complete_draw);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_fail() {
|
||||
ModelUI::screen_install_fail();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_confirm(
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fingerprint: *const cty::uint8_t,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: cty::c_int,
|
||||
) -> u32 {
|
||||
let text = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
|
||||
let mut fingerprint_buffer: [u8; 64] = [0; 64];
|
||||
let fingerprint_str = unsafe {
|
||||
let fingerprint_slice = core::slice::from_raw_parts(fingerprint, 32);
|
||||
hexlify(fingerprint_slice, &mut fingerprint_buffer);
|
||||
core::str::from_utf8_unchecked(fingerprint_buffer.as_ref())
|
||||
};
|
||||
|
||||
ModelUI::screen_install_confirm(
|
||||
text,
|
||||
version,
|
||||
fingerprint_str,
|
||||
should_keep_seed,
|
||||
is_newvendor,
|
||||
version_cmp,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_confirm() -> u32 {
|
||||
ModelUI::screen_wipe_confirm()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_unlock_bootloader_confirm() -> u32 {
|
||||
ModelUI::screen_unlock_bootloader_confirm()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_unlock_bootloader_success() {
|
||||
ModelUI::screen_unlock_bootloader_success();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
ModelUI::screen_menu(firmware_present)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_intro(
|
||||
bld_version: *const cty::c_char,
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fw_ok: bool,
|
||||
) -> u32 {
|
||||
let vendor = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
let bld_version = unwrap!(unsafe { from_c_str(bld_version) });
|
||||
|
||||
ModelUI::screen_intro(bld_version, vendor, version, fw_ok)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_empty(fading: bool) {
|
||||
ModelUI::screen_boot_empty(fading)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
ModelUI::screen_wipe_progress(progress, initialize)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool) {
|
||||
ModelUI::screen_install_progress(progress, initialize, initial_setup)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_connect(initial_setup: bool) {
|
||||
ModelUI::screen_connect(initial_setup)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_success() {
|
||||
ModelUI::screen_wipe_success()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_fail() {
|
||||
ModelUI::screen_wipe_fail()
|
||||
}
|
60
core/embed/rust/src/ui/api/common_c.rs
Normal file
60
core/embed/rust/src/ui/api/common_c.rs
Normal file
@ -0,0 +1,60 @@
|
||||
//! Reexporting the `screens` module according to the
|
||||
//! current feature (Trezor model)
|
||||
|
||||
use crate::ui::{
|
||||
component::image::Image,
|
||||
display::{Color, Icon},
|
||||
geometry::{Alignment2D, Point},
|
||||
ui_features::{ModelUI, UIFeaturesCommon},
|
||||
};
|
||||
|
||||
use crate::ui::util::from_c_str;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_fatal_error_rust(
|
||||
title: *const cty::c_char,
|
||||
msg: *const cty::c_char,
|
||||
footer: *const cty::c_char,
|
||||
) {
|
||||
let title = unsafe { from_c_str(title) }.unwrap_or("");
|
||||
let msg = unsafe { from_c_str(msg) }.unwrap_or("");
|
||||
let footer = unsafe { from_c_str(footer) }.unwrap_or("");
|
||||
|
||||
ModelUI::screen_fatal_error(title, msg, footer);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_full() {
|
||||
ModelUI::screen_boot_full();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn display_icon(
|
||||
x: cty::int16_t,
|
||||
y: cty::int16_t,
|
||||
data: *const cty::uint8_t,
|
||||
data_len: cty::uint32_t,
|
||||
fg_color: cty::uint16_t,
|
||||
bg_color: cty::uint16_t,
|
||||
) {
|
||||
let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) };
|
||||
let icon = Icon::new(data_slice);
|
||||
icon.draw(
|
||||
Point::new(x, y),
|
||||
Alignment2D::TOP_LEFT,
|
||||
Color::from_u16(fg_color),
|
||||
Color::from_u16(bg_color),
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn display_image(
|
||||
x: cty::int16_t,
|
||||
y: cty::int16_t,
|
||||
data: *const cty::uint8_t,
|
||||
data_len: cty::uint32_t,
|
||||
) {
|
||||
let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) };
|
||||
let image = Image::new(data_slice);
|
||||
image.draw(Point::new(x, y), Alignment2D::TOP_LEFT);
|
||||
}
|
4
core/embed/rust/src/ui/api/mod.rs
Normal file
4
core/embed/rust/src/ui/api/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod common_c;
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
pub mod bootloader_c;
|
@ -117,18 +117,6 @@ pub fn render_toif(toif: &Toif, center: Point, fg_color: Color, bg_color: Color)
|
||||
pixeldata_dirty();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn display_image(
|
||||
x: cty::int16_t,
|
||||
y: cty::int16_t,
|
||||
data: *const cty::uint8_t,
|
||||
data_len: cty::uint32_t,
|
||||
) {
|
||||
let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) };
|
||||
let image = Image::new(data_slice);
|
||||
image.draw(Point::new(x, y), Alignment2D::TOP_LEFT);
|
||||
}
|
||||
|
||||
#[cfg(feature = "dma2d")]
|
||||
pub fn image(image: &Image, center: Point) {
|
||||
let r = Rect::from_center_and_size(center, image.toif.size());
|
||||
@ -303,25 +291,6 @@ impl<'i> Toif<'i> {
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn display_icon(
|
||||
x: cty::int16_t,
|
||||
y: cty::int16_t,
|
||||
data: *const cty::uint8_t,
|
||||
data_len: cty::uint32_t,
|
||||
fg_color: cty::uint16_t,
|
||||
bg_color: cty::uint16_t,
|
||||
) {
|
||||
let data_slice = unsafe { core::slice::from_raw_parts(data, data_len as usize) };
|
||||
let icon = Icon::new(data_slice);
|
||||
icon.draw(
|
||||
Point::new(x, y),
|
||||
Alignment2D::TOP_LEFT,
|
||||
Color::from_u16(fg_color),
|
||||
Color::from_u16(bg_color),
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct Icon {
|
||||
pub toif: Toif<'static>,
|
||||
|
@ -9,22 +9,11 @@ use crate::ui::event::TouchEvent;
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx, Never},
|
||||
display,
|
||||
geometry::Rect,
|
||||
ui_features::ModelUI,
|
||||
UIFeaturesCommon,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
pub trait SimplifiedFeatures {
|
||||
fn fadein() {}
|
||||
fn fadeout() {}
|
||||
|
||||
const SCREEN: Rect;
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "model_tr", not(feature = "model_tt")))]
|
||||
pub type ModelFeatures = crate::ui::model_tr::ModelTRFeatures;
|
||||
#[cfg(feature = "model_tt")]
|
||||
pub type ModelFeatures = crate::ui::model_tt::ModelTTFeatures;
|
||||
|
||||
pub trait ReturnToC {
|
||||
fn return_to_c(self) -> u32;
|
||||
}
|
||||
@ -79,12 +68,12 @@ where
|
||||
F: Component,
|
||||
F::Msg: ReturnToC,
|
||||
{
|
||||
frame.place(ModelFeatures::SCREEN);
|
||||
ModelFeatures::fadeout();
|
||||
frame.place(ModelUI::SCREEN);
|
||||
ModelUI::fadeout();
|
||||
display::sync();
|
||||
frame.paint();
|
||||
display::refresh();
|
||||
ModelFeatures::fadein();
|
||||
ModelUI::fadein();
|
||||
|
||||
#[cfg(feature = "button")]
|
||||
while button_eval().is_some() {}
|
||||
@ -115,14 +104,14 @@ pub fn show<F>(frame: &mut F, fading: bool)
|
||||
where
|
||||
F: Component,
|
||||
{
|
||||
frame.place(ModelFeatures::SCREEN);
|
||||
frame.place(ModelUI::SCREEN);
|
||||
if fading {
|
||||
ModelFeatures::fadeout()
|
||||
ModelUI::fadeout()
|
||||
};
|
||||
display::sync();
|
||||
frame.paint();
|
||||
display::refresh();
|
||||
if fading {
|
||||
ModelFeatures::fadein()
|
||||
ModelUI::fadein()
|
||||
};
|
||||
}
|
||||
|
@ -8,13 +8,16 @@ pub mod display;
|
||||
pub mod event;
|
||||
pub mod geometry;
|
||||
pub mod lerp;
|
||||
pub mod screens;
|
||||
#[macro_use]
|
||||
pub mod util;
|
||||
|
||||
pub mod layout;
|
||||
|
||||
mod api;
|
||||
#[cfg(feature = "model_tr")]
|
||||
pub mod model_tr;
|
||||
#[cfg(feature = "model_tt")]
|
||||
pub mod model_tt;
|
||||
pub mod ui_features;
|
||||
|
||||
pub use ui_features::UIFeaturesCommon;
|
||||
|
@ -1,7 +1,6 @@
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
strutil::hexlify,
|
||||
trezorhal::secbool::secbool,
|
||||
ui::{
|
||||
component::{connect::Connect, Label, LineBreaking::BreakWordsNoHyphen},
|
||||
@ -10,7 +9,6 @@ use crate::{
|
||||
display::{self, Color, Font, Icon},
|
||||
geometry::{Alignment2D, Offset, Point, Rect},
|
||||
layout::simplified::{run, show, ReturnToC},
|
||||
util::{from_c_array, from_c_str},
|
||||
},
|
||||
};
|
||||
|
||||
@ -23,12 +21,14 @@ use super::{
|
||||
bootloader::{BLD_BG, BLD_FG, ICON_ALERT, ICON_SPINNER, ICON_SUCCESS},
|
||||
ICON_ARM_LEFT, ICON_ARM_RIGHT, TEXT_BOLD, TEXT_NORMAL, WHITE,
|
||||
},
|
||||
ModelTRFeatures,
|
||||
};
|
||||
|
||||
mod intro;
|
||||
mod menu;
|
||||
mod welcome;
|
||||
|
||||
use crate::ui::ui_features::UIFeaturesBootloader;
|
||||
use intro::Intro;
|
||||
use menu::Menu;
|
||||
use welcome::Welcome;
|
||||
@ -41,119 +41,7 @@ impl ReturnToC for ConfirmMsg {
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_confirm(
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fingerprint: *const cty::uint8_t,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: cty::c_int,
|
||||
) -> u32 {
|
||||
let text = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
|
||||
let mut fingerprint_buffer: [u8; 64] = [0; 64];
|
||||
let fingerprint_str = unsafe {
|
||||
let fingerprint_slice = core::slice::from_raw_parts(fingerprint, 32);
|
||||
hexlify(fingerprint_slice, &mut fingerprint_buffer);
|
||||
core::str::from_utf8_unchecked(fingerprint_buffer.as_ref())
|
||||
};
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(text));
|
||||
|
||||
let title_str = if is_newvendor {
|
||||
"CHANGE FW VENDOR"
|
||||
} else if version_cmp > 0 {
|
||||
"UPDATE FIRMWARE"
|
||||
} else if version_cmp == 0 {
|
||||
"REINSTALL FW"
|
||||
} else {
|
||||
"DOWNGRADE FW"
|
||||
};
|
||||
|
||||
let message = Label::left_aligned(version_str.as_str(), TEXT_NORMAL).vertically_centered();
|
||||
let fingerprint = Label::left_aligned(
|
||||
fingerprint_str,
|
||||
TEXT_NORMAL.with_line_breaking(BreakWordsNoHyphen),
|
||||
)
|
||||
.vertically_centered();
|
||||
|
||||
let alert =
|
||||
(!should_keep_seed).then_some(Label::left_aligned("Seed will be erased!", TEXT_NORMAL));
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, title_str, message, alert, "INSTALL", false)
|
||||
.with_info_screen("FW FINGERPRINT", fingerprint);
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_confirm() -> u32 {
|
||||
let message =
|
||||
Label::left_aligned("Seed and firmware will be erased!", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, "FACTORY RESET", message, None, "RESET", false);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_unlock_bootloader_confirm() -> u32 {
|
||||
let message =
|
||||
Label::left_aligned("This action cannot be undone!", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, "UNLOCK BOOTLOADER?", message, None, "UNLOCK", true);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_unlock_bootloader_success() {
|
||||
let title = Label::centered("Bootloader unlocked", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect the\ndevice", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
run(&mut Menu::new(firmware_present))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_intro(
|
||||
bld_version: *const cty::c_char,
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fw_ok: bool,
|
||||
) -> u32 {
|
||||
let vendor = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
let bld_version = unwrap!(unsafe { from_c_str(bld_version) });
|
||||
|
||||
let mut title_str: BootloaderString = String::new();
|
||||
unwrap!(title_str.push_str("BOOTLOADER "));
|
||||
unwrap!(title_str.push_str(bld_version));
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let mut frame = Intro::new(title_str.as_str(), version_str.as_str(), fw_ok);
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
impl ModelTRFeatures {
|
||||
fn screen_progress(
|
||||
text: &str,
|
||||
text2: &str,
|
||||
@ -196,86 +84,37 @@ fn screen_progress(
|
||||
|
||||
display::refresh();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_progress(progress: u16, initialize: bool, _initial_setup: bool) {
|
||||
screen_progress(
|
||||
"Installing",
|
||||
"firmware",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_BG,
|
||||
Some((ICON_SUCCESS, BLD_FG)),
|
||||
impl UIFeaturesBootloader for ModelTRFeatures {
|
||||
fn screen_welcome() {
|
||||
let mut frame = Welcome::new();
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn bld_continue_label(bg_color: Color) {
|
||||
display::text_center(
|
||||
Point::new(constant::WIDTH / 2, HEIGHT - 2),
|
||||
"CONTINUE",
|
||||
Font::NORMAL,
|
||||
WHITE,
|
||||
bg_color,
|
||||
);
|
||||
ICON_ARM_LEFT.draw(
|
||||
Point::new(constant::WIDTH / 2 - 36, HEIGHT - 6),
|
||||
Alignment2D::TOP_LEFT,
|
||||
WHITE,
|
||||
bg_color,
|
||||
);
|
||||
ICON_ARM_RIGHT.draw(
|
||||
Point::new(constant::WIDTH / 2 + 25, HEIGHT - 6),
|
||||
Alignment2D::TOP_LEFT,
|
||||
WHITE,
|
||||
bg_color,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
screen_progress(
|
||||
"Resetting",
|
||||
"Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_BG,
|
||||
Some((ICON_SUCCESS, BLD_FG)),
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_connect(_initial_setup: bool) {
|
||||
let mut frame = Connect::new("Waiting for host...", BLD_FG, BLD_BG);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_success() {
|
||||
let title = Label::centered("Trezor Reset", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_fail() {
|
||||
let title = Label::centered("Reset failed", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_empty(_fading: bool) {
|
||||
display::rect_fill(SCREEN, BLD_BG);
|
||||
|
||||
let mut frame = WelcomeScreen::new(true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_fail() {
|
||||
let title = Label::centered("Install failed", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_success(
|
||||
restart_seconds: u8,
|
||||
_initial_setup: bool,
|
||||
complete_draw: bool,
|
||||
) {
|
||||
fn screen_install_success(restart_seconds: u8, _initial_setup: bool, complete_draw: bool) {
|
||||
let mut reboot_msg = BootloaderString::new();
|
||||
|
||||
if restart_seconds >= 1 {
|
||||
@ -291,35 +130,160 @@ extern "C" fn screen_install_success(
|
||||
|
||||
let content = Label::centered(reboot_msg.as_str(), TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, complete_draw);
|
||||
let mut frame =
|
||||
ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, complete_draw);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_welcome() {
|
||||
let mut frame = Welcome::new();
|
||||
fn screen_install_fail() {
|
||||
let title = Label::centered("Install failed", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn bld_continue_label(bg_color: cty::uint16_t) {
|
||||
display::text_center(
|
||||
Point::new(constant::WIDTH / 2, HEIGHT - 2),
|
||||
"CONTINUE",
|
||||
Font::NORMAL,
|
||||
WHITE,
|
||||
Color::from_u16(bg_color),
|
||||
);
|
||||
ICON_ARM_LEFT.draw(
|
||||
Point::new(constant::WIDTH / 2 - 36, HEIGHT - 6),
|
||||
Alignment2D::TOP_LEFT,
|
||||
WHITE,
|
||||
Color::from_u16(bg_color),
|
||||
);
|
||||
ICON_ARM_RIGHT.draw(
|
||||
Point::new(constant::WIDTH / 2 + 25, HEIGHT - 6),
|
||||
Alignment2D::TOP_LEFT,
|
||||
WHITE,
|
||||
Color::from_u16(bg_color),
|
||||
fn screen_install_confirm(
|
||||
vendor: &str,
|
||||
version: &str,
|
||||
fingerprint: &str,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: i32,
|
||||
) -> u32 {
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let title_str = if is_newvendor {
|
||||
"CHANGE FW VENDOR"
|
||||
} else if version_cmp > 0 {
|
||||
"UPDATE FIRMWARE"
|
||||
} else if version_cmp == 0 {
|
||||
"REINSTALL FW"
|
||||
} else {
|
||||
"DOWNGRADE FW"
|
||||
};
|
||||
|
||||
let message = Label::left_aligned(version_str.as_str(), TEXT_NORMAL).vertically_centered();
|
||||
let fingerprint = Label::left_aligned(
|
||||
fingerprint,
|
||||
TEXT_NORMAL.with_line_breaking(BreakWordsNoHyphen),
|
||||
)
|
||||
.vertically_centered();
|
||||
|
||||
let alert =
|
||||
(!should_keep_seed).then_some(Label::left_aligned("Seed will be erased!", TEXT_NORMAL));
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, title_str, message, alert, "INSTALL", false)
|
||||
.with_info_screen("FW FINGERPRINT", fingerprint);
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_wipe_confirm() -> u32 {
|
||||
let message = Label::left_aligned("Seed and firmware will be erased!", TEXT_NORMAL)
|
||||
.vertically_centered();
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, "FACTORY RESET", message, None, "RESET", false);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_confirm() -> u32 {
|
||||
let message =
|
||||
Label::left_aligned("This action cannot be undone!", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, "UNLOCK BOOTLOADER?", message, None, "UNLOCK", true);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_success() {
|
||||
let title = Label::centered("Bootloader unlocked", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect the\ndevice", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
run(&mut Menu::new(firmware_present))
|
||||
}
|
||||
|
||||
fn screen_intro(bld_version: &str, vendor: &str, version: &str, fw_ok: bool) -> u32 {
|
||||
let mut title_str: BootloaderString = String::new();
|
||||
unwrap!(title_str.push_str("BOOTLOADER "));
|
||||
unwrap!(title_str.push_str(bld_version));
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let mut frame = Intro::new(title_str.as_str(), version_str.as_str(), fw_ok);
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_boot_empty(_fading: bool) {
|
||||
display::rect_fill(SCREEN, BLD_BG);
|
||||
|
||||
let mut frame = WelcomeScreen::new(true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
ModelTRFeatures::screen_progress(
|
||||
"Resetting",
|
||||
"Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_BG,
|
||||
Some((ICON_SUCCESS, BLD_FG)),
|
||||
);
|
||||
}
|
||||
|
||||
fn screen_install_progress(progress: u16, initialize: bool, _initial_setup: bool) {
|
||||
ModelTRFeatures::screen_progress(
|
||||
"Installing",
|
||||
"firmware",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_BG,
|
||||
Some((ICON_SUCCESS, BLD_FG)),
|
||||
);
|
||||
}
|
||||
|
||||
fn screen_connect(_initial_setup: bool) {
|
||||
let mut frame = Connect::new("Waiting for host...", BLD_FG, BLD_BG);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
fn screen_wipe_success() {
|
||||
let title = Label::centered("Trezor Reset", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_SPINNER, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
|
||||
fn screen_wipe_fail() {
|
||||
let title = Label::centered("Reset failed", TEXT_BOLD).vertically_centered();
|
||||
|
||||
let content =
|
||||
Label::centered("Please reconnect\nthe device", TEXT_NORMAL).vertically_centered();
|
||||
|
||||
let mut frame = ResultScreen::new(BLD_FG, BLD_BG, ICON_ALERT, title, content, true);
|
||||
show(&mut frame, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{geometry::Rect, layout::simplified::SimplifiedFeatures};
|
||||
use super::{geometry::Rect, UIFeaturesCommon};
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
pub mod bootloader;
|
||||
@ -7,11 +7,19 @@ pub mod component;
|
||||
pub mod constant;
|
||||
#[cfg(feature = "micropython")]
|
||||
pub mod layout;
|
||||
pub mod screens;
|
||||
mod screens;
|
||||
pub mod theme;
|
||||
|
||||
pub struct ModelTRFeatures {}
|
||||
|
||||
impl SimplifiedFeatures for ModelTRFeatures {
|
||||
impl UIFeaturesCommon for ModelTRFeatures {
|
||||
const SCREEN: Rect = constant::SCREEN;
|
||||
|
||||
fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
|
||||
screens::screen_fatal_error(title, msg, footer);
|
||||
}
|
||||
|
||||
fn screen_boot_full() {
|
||||
screens::screen_boot_full();
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
|
||||
frame.paint();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_full() {
|
||||
pub fn screen_boot_full() {
|
||||
let mut frame = WelcomeScreen::new(false);
|
||||
frame.place(screen());
|
||||
display::sync();
|
||||
|
@ -1,14 +1,12 @@
|
||||
use heapless::String;
|
||||
|
||||
use crate::{
|
||||
strutil::hexlify,
|
||||
trezorhal::secbool::secbool,
|
||||
ui::{
|
||||
component::{connect::Connect, Label},
|
||||
display::{self, Color, Font, Icon},
|
||||
geometry::{Point, Rect},
|
||||
layout::simplified::{run, show, SimplifiedFeatures as _},
|
||||
util::{from_c_array, from_c_str},
|
||||
layout::simplified::{run, show},
|
||||
},
|
||||
};
|
||||
|
||||
@ -30,6 +28,7 @@ use super::{
|
||||
ModelTTFeatures,
|
||||
};
|
||||
|
||||
use crate::ui::{ui_features::UIFeaturesBootloader, UIFeaturesCommon};
|
||||
use intro::Intro;
|
||||
use menu::Menu;
|
||||
|
||||
@ -43,120 +42,7 @@ const RECONNECT_MESSAGE: &str = "PLEASE RECONNECT\nTHE DEVICE";
|
||||
|
||||
const SCREEN: Rect = ModelTTFeatures::SCREEN;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_confirm(
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fingerprint: *const cty::uint8_t,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: cty::c_int,
|
||||
) -> u32 {
|
||||
let text = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
|
||||
let mut fingerprint_buffer: [u8; 64] = [0; 64];
|
||||
let fingerprint_str = unsafe {
|
||||
let fingerprint_slice = core::slice::from_raw_parts(fingerprint, 32);
|
||||
hexlify(fingerprint_slice, &mut fingerprint_buffer);
|
||||
core::str::from_utf8_unchecked(fingerprint_buffer.as_ref())
|
||||
};
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(text));
|
||||
|
||||
let title_str = if is_newvendor {
|
||||
"CHANGE FW\nVENDOR"
|
||||
} else if version_cmp > 0 {
|
||||
"UPDATE FIRMWARE"
|
||||
} else if version_cmp == 0 {
|
||||
"REINSTALL FW"
|
||||
} else {
|
||||
"DOWNGRADE FW"
|
||||
};
|
||||
let title = Label::left_aligned(title_str, TEXT_BOLD).vertically_centered();
|
||||
let msg = Label::left_aligned(version_str.as_ref(), TEXT_NORMAL);
|
||||
let alert =
|
||||
(!should_keep_seed).then_some(Label::left_aligned("SEED WILL BE ERASED!", TEXT_BOLD));
|
||||
|
||||
let (left, right) = if should_keep_seed {
|
||||
let l = Button::with_text("CANCEL").styled(button_bld());
|
||||
let r = Button::with_text("INSTALL").styled(button_confirm());
|
||||
(l, r)
|
||||
} else {
|
||||
let l = Button::with_icon(Icon::new(X24)).styled(button_bld());
|
||||
let r = Button::with_icon(Icon::new(CHECK24)).styled(button_confirm());
|
||||
(l, r)
|
||||
};
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, left, right, ConfirmTitle::Text(title), msg).with_info(
|
||||
"FW FINGERPRINT",
|
||||
fingerprint_str,
|
||||
button_bld_menu(),
|
||||
);
|
||||
|
||||
if let Some(alert) = alert {
|
||||
frame = frame.with_alert(alert);
|
||||
}
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_confirm() -> u32 {
|
||||
let icon = Icon::new(FIRE40);
|
||||
|
||||
let msg = Label::centered(
|
||||
"Are you sure you want to factory reset the device?",
|
||||
TEXT_WIPE_NORMAL,
|
||||
);
|
||||
let alert = Label::centered("SEED AND FIRMWARE\nWILL BE ERASED!", TEXT_WIPE_BOLD);
|
||||
|
||||
let right = Button::with_text("RESET").styled(button_wipe_confirm());
|
||||
let left = Button::with_text("CANCEL").styled(button_wipe_cancel());
|
||||
|
||||
let mut frame =
|
||||
Confirm::new(BLD_WIPE_COLOR, left, right, ConfirmTitle::Icon(icon), msg).with_alert(alert);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
run(&mut Menu::new(firmware_present))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_intro(
|
||||
bld_version: *const cty::c_char,
|
||||
vendor_str: *const cty::c_char,
|
||||
vendor_str_len: u8,
|
||||
version: *const cty::c_char,
|
||||
fw_ok: bool,
|
||||
) -> u32 {
|
||||
let vendor = unwrap!(unsafe { from_c_array(vendor_str, vendor_str_len as usize) });
|
||||
let version = unwrap!(unsafe { from_c_str(version) });
|
||||
let bld_version = unwrap!(unsafe { from_c_str(bld_version) });
|
||||
|
||||
let mut title_str: BootloaderString = String::new();
|
||||
unwrap!(title_str.push_str("BOOTLOADER "));
|
||||
unwrap!(title_str.push_str(bld_version));
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let mut frame = Intro::new(title_str.as_str(), version_str.as_str(), fw_ok);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
impl ModelTTFeatures {
|
||||
fn screen_progress(
|
||||
text: &str,
|
||||
progress: u16,
|
||||
@ -184,95 +70,6 @@ fn screen_progress(
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool) {
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let fg_color = if initial_setup { FG } else { BLD_FG };
|
||||
|
||||
screen_progress(
|
||||
"Installing firmware",
|
||||
progress,
|
||||
initialize,
|
||||
fg_color,
|
||||
bg_color,
|
||||
Some((Icon::new(DOWNLOAD32), fg_color)),
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
screen_progress(
|
||||
"Resetting Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_WIPE_COLOR,
|
||||
Some((Icon::new(FIRE32), BLD_FG)),
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_connect(initial_setup: bool) {
|
||||
let bg = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let mut frame = Connect::new("Waiting for host...", BLD_TITLE_COLOR, bg);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_success() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_WIPE,
|
||||
Icon::new(CHECK40),
|
||||
"Trezor reset\nsuccessfully",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_WIPE.title_style()).vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_wipe_fail() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_WIPE,
|
||||
Icon::new(WARNING40),
|
||||
"Trezor reset was\nnot successful",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_WIPE.title_style()).vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_empty(fading: bool) {
|
||||
if fading {
|
||||
ModelTTFeatures::fadeout();
|
||||
}
|
||||
|
||||
display::rect_fill(SCREEN, BLACK);
|
||||
|
||||
let mut frame = WelcomeScreen::new(true);
|
||||
show(&mut frame, false);
|
||||
|
||||
if fading {
|
||||
ModelTTFeatures::fadein();
|
||||
} else {
|
||||
display::set_backlight(BACKLIGHT_NORMAL);
|
||||
}
|
||||
display::refresh();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_fail() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_FW_INSTALL,
|
||||
Icon::new(WARNING40),
|
||||
"Firmware installation was not successful",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_FW_INSTALL.title_style()).vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn screen_install_success_bld(msg: &str, complete_draw: bool) {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_FW_INSTALL,
|
||||
@ -294,13 +91,25 @@ fn screen_install_success_initial(msg: &str, complete_draw: bool) {
|
||||
);
|
||||
show(&mut frame, complete_draw);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_install_success(
|
||||
restart_seconds: u8,
|
||||
initial_setup: bool,
|
||||
complete_draw: bool,
|
||||
) {
|
||||
impl UIFeaturesBootloader for ModelTTFeatures {
|
||||
fn screen_welcome() {
|
||||
let mut frame = Welcome::new();
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn bld_continue_label(bg_color: Color) {
|
||||
display::text_center(
|
||||
Point::new(SCREEN.width() / 2, SCREEN.height() - 5),
|
||||
"click to continue ...",
|
||||
Font::NORMAL,
|
||||
WHITE,
|
||||
bg_color,
|
||||
);
|
||||
}
|
||||
|
||||
fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool) {
|
||||
let mut reboot_msg = BootloaderString::new();
|
||||
|
||||
if restart_seconds >= 1 {
|
||||
@ -313,26 +122,187 @@ extern "C" fn screen_install_success(
|
||||
}
|
||||
|
||||
if initial_setup {
|
||||
screen_install_success_initial(reboot_msg.as_str(), complete_draw)
|
||||
ModelTTFeatures::screen_install_success_initial(reboot_msg.as_str(), complete_draw)
|
||||
} else {
|
||||
screen_install_success_bld(reboot_msg.as_str(), complete_draw)
|
||||
ModelTTFeatures::screen_install_success_bld(reboot_msg.as_str(), complete_draw)
|
||||
}
|
||||
display::refresh();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_welcome() {
|
||||
let mut frame = Welcome::new();
|
||||
fn screen_install_fail() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_FW_INSTALL,
|
||||
Icon::new(WARNING40),
|
||||
"Firmware installation was not successful",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_FW_INSTALL.title_style())
|
||||
.vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn bld_continue_label(bg_color: cty::uint16_t) {
|
||||
display::text_center(
|
||||
Point::new(SCREEN.width() / 2, SCREEN.height() - 5),
|
||||
"click to continue ...",
|
||||
Font::NORMAL,
|
||||
WHITE,
|
||||
Color::from_u16(bg_color),
|
||||
);
|
||||
fn screen_install_confirm(
|
||||
vendor: &str,
|
||||
version: &str,
|
||||
fingerprint: &str,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: i32,
|
||||
) -> u32 {
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let title_str = if is_newvendor {
|
||||
"CHANGE FW\nVENDOR"
|
||||
} else if version_cmp > 0 {
|
||||
"UPDATE FIRMWARE"
|
||||
} else if version_cmp == 0 {
|
||||
"REINSTALL FW"
|
||||
} else {
|
||||
"DOWNGRADE FW"
|
||||
};
|
||||
let title = Label::left_aligned(title_str, TEXT_BOLD).vertically_centered();
|
||||
let msg = Label::left_aligned(version_str.as_ref(), TEXT_NORMAL);
|
||||
let alert =
|
||||
(!should_keep_seed).then_some(Label::left_aligned("SEED WILL BE ERASED!", TEXT_BOLD));
|
||||
|
||||
let (left, right) = if should_keep_seed {
|
||||
let l = Button::with_text("CANCEL").styled(button_bld());
|
||||
let r = Button::with_text("INSTALL").styled(button_confirm());
|
||||
(l, r)
|
||||
} else {
|
||||
let l = Button::with_icon(Icon::new(X24)).styled(button_bld());
|
||||
let r = Button::with_icon(Icon::new(CHECK24)).styled(button_confirm());
|
||||
(l, r)
|
||||
};
|
||||
|
||||
let mut frame = Confirm::new(BLD_BG, left, right, ConfirmTitle::Text(title), msg)
|
||||
.with_info("FW FINGERPRINT", fingerprint, button_bld_menu());
|
||||
|
||||
if let Some(alert) = alert {
|
||||
frame = frame.with_alert(alert);
|
||||
}
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_wipe_confirm() -> u32 {
|
||||
let icon = Icon::new(FIRE40);
|
||||
|
||||
let msg = Label::centered(
|
||||
"Are you sure you want to factory reset the device?",
|
||||
TEXT_WIPE_NORMAL,
|
||||
);
|
||||
let alert = Label::centered("SEED AND FIRMWARE\nWILL BE ERASED!", TEXT_WIPE_BOLD);
|
||||
|
||||
let right = Button::with_text("RESET").styled(button_wipe_confirm());
|
||||
let left = Button::with_text("CANCEL").styled(button_wipe_cancel());
|
||||
|
||||
let mut frame = Confirm::new(BLD_WIPE_COLOR, left, right, ConfirmTitle::Icon(icon), msg)
|
||||
.with_alert(alert);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_confirm() -> u32 {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn screen_unlock_bootloader_success() {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn screen_menu(firmware_present: secbool) -> u32 {
|
||||
run(&mut Menu::new(firmware_present))
|
||||
}
|
||||
|
||||
fn screen_intro(bld_version: &str, vendor: &str, version: &str, fw_ok: bool) -> u32 {
|
||||
let mut title_str: BootloaderString = String::new();
|
||||
unwrap!(title_str.push_str("BOOTLOADER "));
|
||||
unwrap!(title_str.push_str(bld_version));
|
||||
|
||||
let mut version_str: BootloaderString = String::new();
|
||||
unwrap!(version_str.push_str("Firmware version "));
|
||||
unwrap!(version_str.push_str(version));
|
||||
unwrap!(version_str.push_str("\nby "));
|
||||
unwrap!(version_str.push_str(vendor));
|
||||
|
||||
let mut frame = Intro::new(title_str.as_str(), version_str.as_str(), fw_ok);
|
||||
|
||||
run(&mut frame)
|
||||
}
|
||||
|
||||
fn screen_boot_empty(fading: bool) {
|
||||
if fading {
|
||||
ModelTTFeatures::fadeout();
|
||||
}
|
||||
|
||||
display::rect_fill(SCREEN, BLACK);
|
||||
|
||||
let mut frame = WelcomeScreen::new(true);
|
||||
show(&mut frame, false);
|
||||
|
||||
if fading {
|
||||
ModelTTFeatures::fadein();
|
||||
} else {
|
||||
display::set_backlight(BACKLIGHT_NORMAL);
|
||||
}
|
||||
display::refresh();
|
||||
}
|
||||
|
||||
fn screen_wipe_progress(progress: u16, initialize: bool) {
|
||||
ModelTTFeatures::screen_progress(
|
||||
"Resetting Trezor",
|
||||
progress,
|
||||
initialize,
|
||||
BLD_FG,
|
||||
BLD_WIPE_COLOR,
|
||||
Some((Icon::new(FIRE32), BLD_FG)),
|
||||
)
|
||||
}
|
||||
|
||||
fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool) {
|
||||
let bg_color = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let fg_color = if initial_setup { FG } else { BLD_FG };
|
||||
|
||||
ModelTTFeatures::screen_progress(
|
||||
"Installing firmware",
|
||||
progress,
|
||||
initialize,
|
||||
fg_color,
|
||||
bg_color,
|
||||
Some((Icon::new(DOWNLOAD32), fg_color)),
|
||||
)
|
||||
}
|
||||
|
||||
fn screen_connect(initial_setup: bool) {
|
||||
let bg = if initial_setup { WELCOME_COLOR } else { BLD_BG };
|
||||
let mut frame = Connect::new("Waiting for host...", BLD_TITLE_COLOR, bg);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn screen_wipe_success() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_WIPE,
|
||||
Icon::new(CHECK40),
|
||||
"Trezor reset\nsuccessfully",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_WIPE.title_style()).vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
|
||||
fn screen_wipe_fail() {
|
||||
let mut frame = ResultScreen::new(
|
||||
&RESULT_WIPE,
|
||||
Icon::new(WARNING40),
|
||||
"Trezor reset was\nnot successful",
|
||||
Label::centered(RECONNECT_MESSAGE, RESULT_WIPE.title_style()).vertically_centered(),
|
||||
true,
|
||||
);
|
||||
show(&mut frame, true);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{geometry::Rect, layout::simplified::SimplifiedFeatures};
|
||||
use super::{geometry::Rect, UIFeaturesCommon};
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
pub mod bootloader;
|
||||
@ -8,11 +8,11 @@ pub mod theme;
|
||||
|
||||
#[cfg(feature = "micropython")]
|
||||
pub mod layout;
|
||||
pub mod screens;
|
||||
mod screens;
|
||||
|
||||
pub struct ModelTTFeatures {}
|
||||
pub struct ModelTTFeatures;
|
||||
|
||||
impl SimplifiedFeatures for ModelTTFeatures {
|
||||
impl UIFeaturesCommon for ModelTTFeatures {
|
||||
fn fadein() {
|
||||
#[cfg(feature = "backlight")]
|
||||
crate::ui::display::fade_backlight_duration(theme::BACKLIGHT_NORMAL, 150);
|
||||
@ -24,4 +24,12 @@ impl SimplifiedFeatures for ModelTTFeatures {
|
||||
}
|
||||
|
||||
const SCREEN: Rect = constant::SCREEN;
|
||||
|
||||
fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
|
||||
screens::screen_fatal_error(title, msg, footer);
|
||||
}
|
||||
|
||||
fn screen_boot_full() {
|
||||
screens::screen_boot_full();
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ pub fn screen_fatal_error(title: &str, msg: &str, footer: &str) {
|
||||
frame.paint();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_boot_full() {
|
||||
pub fn screen_boot_full() {
|
||||
let mut frame = WelcomeScreen::new(false);
|
||||
frame.place(screen());
|
||||
display::sync();
|
||||
|
@ -1,21 +0,0 @@
|
||||
//! Reexporting the `screens` module according to the
|
||||
//! current feature (Trezor model)
|
||||
|
||||
#[cfg(all(feature = "model_tr", not(feature = "model_tt")))]
|
||||
pub use super::model_tr::screens::*;
|
||||
#[cfg(feature = "model_tt")]
|
||||
pub use super::model_tt::screens::*;
|
||||
use crate::ui::util::from_c_str;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn screen_fatal_error_rust(
|
||||
title: *const cty::c_char,
|
||||
msg: *const cty::c_char,
|
||||
footer: *const cty::c_char,
|
||||
) {
|
||||
let title = unsafe { from_c_str(title) }.unwrap_or("");
|
||||
let msg = unsafe { from_c_str(msg) }.unwrap_or("");
|
||||
let footer = unsafe { from_c_str(footer) }.unwrap_or("");
|
||||
|
||||
screen_fatal_error(title, msg, footer);
|
||||
}
|
62
core/embed/rust/src/ui/ui_features.rs
Normal file
62
core/embed/rust/src/ui/ui_features.rs
Normal file
@ -0,0 +1,62 @@
|
||||
use crate::ui::geometry::Rect;
|
||||
#[cfg(feature = "bootloader")]
|
||||
use crate::{trezorhal::secbool::secbool, ui::display::Color};
|
||||
|
||||
pub trait UIFeaturesCommon {
|
||||
fn fadein() {}
|
||||
fn fadeout() {}
|
||||
|
||||
const SCREEN: Rect;
|
||||
|
||||
fn screen_fatal_error(title: &str, msg: &str, footer: &str);
|
||||
|
||||
fn screen_boot_full();
|
||||
}
|
||||
|
||||
#[cfg(feature = "bootloader")]
|
||||
pub trait UIFeaturesBootloader {
|
||||
fn screen_welcome();
|
||||
|
||||
fn bld_continue_label(bg_color: Color);
|
||||
|
||||
fn screen_install_success(restart_seconds: u8, initial_setup: bool, complete_draw: bool);
|
||||
|
||||
fn screen_install_fail();
|
||||
|
||||
fn screen_install_confirm(
|
||||
vendor: &str,
|
||||
version: &str,
|
||||
fingerprint: &str,
|
||||
should_keep_seed: bool,
|
||||
is_newvendor: bool,
|
||||
version_cmp: i32,
|
||||
) -> u32;
|
||||
|
||||
fn screen_wipe_confirm() -> u32;
|
||||
|
||||
fn screen_unlock_bootloader_confirm() -> u32;
|
||||
|
||||
fn screen_unlock_bootloader_success();
|
||||
|
||||
fn screen_menu(firmware_present: secbool) -> u32;
|
||||
|
||||
fn screen_intro(bld_version: &str, vendor: &str, version: &str, fw_ok: bool) -> u32;
|
||||
|
||||
fn screen_boot_empty(fading: bool);
|
||||
|
||||
fn screen_wipe_progress(progress: u16, initialize: bool);
|
||||
|
||||
fn screen_install_progress(progress: u16, initialize: bool, initial_setup: bool);
|
||||
|
||||
fn screen_connect(initial_setup: bool);
|
||||
|
||||
fn screen_wipe_success();
|
||||
|
||||
fn screen_wipe_fail();
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "model_tr", not(feature = "model_tt")))]
|
||||
pub type ModelUI = crate::ui::model_tr::ModelTRFeatures;
|
||||
|
||||
#[cfg(feature = "model_tt")]
|
||||
pub type ModelUI = crate::ui::model_tt::ModelTTFeatures;
|
Loading…
Reference in New Issue
Block a user