1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 04:18:10 +00:00

feat(core): added user adjustable brightness setting

This commit is contained in:
tychovrahe 2024-01-08 23:40:25 +01:00 committed by TychoVrahe
parent 5ec8b58772
commit a65511846b
64 changed files with 1538 additions and 438 deletions

View File

@ -115,6 +115,7 @@ message Features {
Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry directly on the device Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry directly on the device
Capability_Solana = 18; Capability_Solana = 18;
Capability_Translations = 19 [(bitcoin_only) = true]; Capability_Translations = 19 [(bitcoin_only) = true];
Capability_Brightness = 20 [(bitcoin_only) = true];
} }
optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced) optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced)
optional bool sd_card_present = 32; // is SD card present optional bool sd_card_present = 32; // is SD card present
@ -612,3 +613,12 @@ message ShowDeviceTutorial {
*/ */
message UnlockBootloader { message UnlockBootloader {
} }
/**
* Request: Set device brightness
* @start
* @next Success
*/
message SetBrightness {
optional uint32 value = 1; // if not specified, let the user choose
}

View File

@ -127,6 +127,7 @@ enum MessageType {
MessageType_ChangeLanguage = 990 [(bitcoin_only) = true, (wire_in) = true]; MessageType_ChangeLanguage = 990 [(bitcoin_only) = true, (wire_in) = true];
MessageType_TranslationDataRequest = 991 [(bitcoin_only) = true, (wire_out) = true]; MessageType_TranslationDataRequest = 991 [(bitcoin_only) = true, (wire_out) = true];
MessageType_TranslationDataAck = 992 [(bitcoin_only) = true, (wire_in) = true]; MessageType_TranslationDataAck = 992 [(bitcoin_only) = true, (wire_in) = true];
MessageType_SetBrightness = 993 [(bitcoin_only) = true, (wire_in) = true];
MessageType_SetU2FCounter = 63 [(wire_in) = true]; MessageType_SetU2FCounter = 63 [(wire_in) = true];
MessageType_GetNextU2FCounter = 80 [(wire_in) = true]; MessageType_GetNextU2FCounter = 80 [(wire_in) = true];

View File

@ -0,0 +1 @@
[T2T1] Added user adjustable brightness setting.

View File

@ -108,6 +108,7 @@ static void _librust_qstrs(void) {
MP_QSTR_bounds; MP_QSTR_bounds;
MP_QSTR_br_code; MP_QSTR_br_code;
MP_QSTR_br_type; MP_QSTR_br_type;
MP_QSTR_brightness__title;
MP_QSTR_button; MP_QSTR_button;
MP_QSTR_button_event; MP_QSTR_button_event;
MP_QSTR_button_request; MP_QSTR_button_request;
@ -191,6 +192,7 @@ static void _librust_qstrs(void) {
MP_QSTR_confirm_value; MP_QSTR_confirm_value;
MP_QSTR_confirm_with_info; MP_QSTR_confirm_with_info;
MP_QSTR_count; MP_QSTR_count;
MP_QSTR_current;
MP_QSTR_data; MP_QSTR_data;
MP_QSTR_data_hash; MP_QSTR_data_hash;
MP_QSTR_data_len; MP_QSTR_data_len;
@ -590,6 +592,7 @@ static void _librust_qstrs(void) {
MP_QSTR_send__transaction_id; MP_QSTR_send__transaction_id;
MP_QSTR_send__transaction_signed; MP_QSTR_send__transaction_signed;
MP_QSTR_send__you_are_contributing; MP_QSTR_send__you_are_contributing;
MP_QSTR_set_brightness;
MP_QSTR_share_words; MP_QSTR_share_words;
MP_QSTR_share_words__words_in_order; MP_QSTR_share_words__words_in_order;
MP_QSTR_share_words__wrote_down_all; MP_QSTR_share_words__wrote_down_all;

View File

@ -1,6 +1,6 @@
#![allow(dead_code)] #![allow(dead_code)]
use crate::trezorhal::storage::{get, get_length, StorageResult}; use crate::trezorhal::storage::{self, StorageResult};
pub const HOMESCREEN_MAX_SIZE: usize = 16384; pub const HOMESCREEN_MAX_SIZE: usize = 16384;
@ -37,14 +37,29 @@ const SAFETY_CHECK_LEVEL: u16 = APP_DEVICE | 0x0014;
const EXPERIMENTAL_FEATURES: u16 = APP_DEVICE | 0x0015; const EXPERIMENTAL_FEATURES: u16 = APP_DEVICE | 0x0015;
const HIDE_PASSPHRASE_FROM_HOST: u16 = APP_DEVICE | 0x0016; const HIDE_PASSPHRASE_FROM_HOST: u16 = APP_DEVICE | 0x0016;
const SLIP39_EXTENDABLE: u16 = APP_DEVICE | 0x0017; const SLIP39_EXTENDABLE: u16 = APP_DEVICE | 0x0017;
const BRIGHTNESS: u16 = FLAG_PUBLIC | APP_DEVICE | 0x0019;
pub fn get_avatar_len() -> StorageResult<usize> { pub fn get_avatar_len() -> StorageResult<usize> {
get_length(HOMESCREEN) storage::get_length(HOMESCREEN)
} }
pub fn load_avatar(dest: &mut [u8]) -> StorageResult<()> { pub fn load_avatar(dest: &mut [u8]) -> StorageResult<()> {
let dest_len = dest.len(); let dest_len = dest.len();
let result = get(HOMESCREEN, dest)?; let result = storage::get(HOMESCREEN, dest)?;
ensure!(dest_len == result.len(), "Internal error in load_avatar"); ensure!(dest_len == result.len(), "Internal error in load_avatar");
Ok(()) Ok(())
} }
pub fn get_brightness() -> StorageResult<u8> {
let mut dest: [u8; 1] = [0; 1];
let res = storage::get(BRIGHTNESS, &mut dest);
match res {
Ok(_) => Ok(dest[0]),
Err(e) => Err(e),
}
}
pub fn set_brightness(value: u8) -> StorageResult<()> {
let value = [value];
storage::set(BRIGHTNESS, &value)
}

View File

@ -1329,6 +1329,7 @@ pub enum TranslatedString {
words__settings = 929, // "Settings" words__settings = 929, // "Settings"
words__try_again = 930, // "Try again." words__try_again = 930, // "Try again."
reset__slip39_checklist_num_groups_x_template = 931, // "Number of groups: {0}" reset__slip39_checklist_num_groups_x_template = 931, // "Number of groups: {0}"
brightness__title = 932, // "Set brightness"
} }
impl TranslatedString { impl TranslatedString {
@ -2653,6 +2654,7 @@ impl TranslatedString {
Self::words__settings => "Settings", Self::words__settings => "Settings",
Self::words__try_again => "Try again.", Self::words__try_again => "Try again.",
Self::reset__slip39_checklist_num_groups_x_template => "Number of groups: {0}", Self::reset__slip39_checklist_num_groups_x_template => "Number of groups: {0}",
Self::brightness__title => "Set brightness",
} }
} }
@ -3978,6 +3980,7 @@ impl TranslatedString {
Qstr::MP_QSTR_words__settings => Some(Self::words__settings), Qstr::MP_QSTR_words__settings => Some(Self::words__settings),
Qstr::MP_QSTR_words__try_again => Some(Self::words__try_again), Qstr::MP_QSTR_words__try_again => Some(Self::words__try_again),
Qstr::MP_QSTR_reset__slip39_checklist_num_groups_x_template => Some(Self::reset__slip39_checklist_num_groups_x_template), Qstr::MP_QSTR_reset__slip39_checklist_num_groups_x_template => Some(Self::reset__slip39_checklist_num_groups_x_template),
Qstr::MP_QSTR_brightness__title => Some(Self::brightness__title),
_ => None, _ => None,
} }
} }

View File

@ -16,6 +16,7 @@ use super::{
bl_confirm::{Confirm, ConfirmTitle}, bl_confirm::{Confirm, ConfirmTitle},
Button, ResultScreen, WelcomeScreen, Button, ResultScreen, WelcomeScreen,
}, },
theme,
theme::{ theme::{
bootloader::{ bootloader::{
button_bld, button_bld_menu, button_confirm, button_wipe_cancel, button_wipe_confirm, button_bld, button_bld_menu, button_confirm, button_wipe_cancel, button_wipe_confirm,
@ -23,7 +24,7 @@ use super::{
FIRE40, RESULT_FW_INSTALL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL, TEXT_WIPE_BOLD, FIRE40, RESULT_FW_INSTALL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL, TEXT_WIPE_BOLD,
TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
}, },
BACKLIGHT_NORMAL, GREEN_LIGHT, GREY, GREEN_LIGHT, GREY,
}, },
ModelMercuryFeatures, ModelMercuryFeatures,
}; };
@ -344,7 +345,7 @@ impl UIFeaturesBootloader for ModelMercuryFeatures {
if fading { if fading {
Self::fadein(); Self::fadein();
} else { } else {
display::set_backlight(BACKLIGHT_NORMAL); display::set_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -207,7 +207,7 @@ where
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }
@ -237,7 +237,7 @@ where
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -387,7 +387,7 @@ impl Component for PassphraseKeyboard {
} }
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -19,6 +19,7 @@ mod keyboard;
mod loader; mod loader;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
mod number_input; mod number_input;
pub mod number_input_slider;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
mod page; mod page;
mod progress; mod progress;
@ -26,6 +27,8 @@ mod prompt_screen;
mod result; mod result;
mod scroll; mod scroll;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
mod set_brightness;
#[cfg(feature = "translations")]
mod share_words; mod share_words;
mod simple_page; mod simple_page;
mod status_screen; mod status_screen;
@ -60,12 +63,16 @@ pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet};
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
pub use number_input::{NumberInputDialog, NumberInputDialogMsg}; pub use number_input::{NumberInputDialog, NumberInputDialogMsg};
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
pub use number_input_slider::NumberInputSliderDialog;
#[cfg(feature = "translations")]
pub use page::ButtonPage; pub use page::ButtonPage;
pub use progress::Progress; pub use progress::Progress;
pub use prompt_screen::PromptScreen; pub use prompt_screen::PromptScreen;
pub use result::{ResultFooter, ResultScreen, ResultStyle}; pub use result::{ResultFooter, ResultScreen, ResultStyle};
pub use scroll::ScrollBar; pub use scroll::ScrollBar;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
pub use set_brightness::SetBrightnessDialog;
#[cfg(feature = "translations")]
pub use share_words::ShareWords; pub use share_words::ShareWords;
pub use simple_page::SimplePage; pub use simple_page::SimplePage;
pub use status_screen::StatusScreen; pub use status_screen::StatusScreen;

View File

@ -0,0 +1,204 @@
use crate::ui::{
component::{base::ComponentExt, Child, Component, Event, EventCtx},
constant::screen,
display,
event::TouchEvent,
geometry::{Grid, Insets, Point, Rect},
shape::{self, Renderer},
};
use super::{theme, Button, ButtonMsg};
pub enum NumberInputSliderDialogMsg {
Changed(u16),
Confirmed,
Cancelled,
}
pub struct NumberInputSliderDialog {
area: Rect,
input: Child<NumberInputSlider>,
cancel_button: Child<Button>,
confirm_button: Child<Button>,
}
impl NumberInputSliderDialog {
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
Self {
area: Rect::zero(),
input: NumberInputSlider::new(min, max, init_value).into_child(),
cancel_button: Button::with_text("CANCEL".into())
.styled(theme::button_cancel())
.into_child(),
confirm_button: Button::with_text("CONFIRM".into())
.styled(theme::button_confirm())
.into_child(),
}
}
pub fn value(&self) -> u16 {
self.input.inner().value
}
}
impl Component for NumberInputSliderDialog {
type Msg = NumberInputSliderDialogMsg;
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
let button_height = theme::BUTTON_HEIGHT;
let content_area = self.area.inset(Insets::top(2 * theme::BUTTON_SPACING));
let (_, content_area) = content_area.split_top(30);
let (input_area, _) = content_area.split_top(15);
let (_, button_area) = content_area.split_bottom(button_height);
let grid = Grid::new(button_area, 1, 2).with_spacing(theme::KEYBOARD_SPACING);
self.input.place(input_area.inset(Insets::sides(20)));
self.cancel_button.place(grid.row_col(0, 0));
self.confirm_button.place(grid.row_col(0, 1));
bounds
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
if let Some(value) = self.input.event(ctx, event) {
return Some(Self::Msg::Changed(value));
}
if let Some(ButtonMsg::Clicked) = self.cancel_button.event(ctx, event) {
return Some(Self::Msg::Cancelled);
}
if let Some(ButtonMsg::Clicked) = self.confirm_button.event(ctx, event) {
return Some(Self::Msg::Confirmed);
};
None
}
fn paint(&mut self) {
self.input.paint();
self.cancel_button.paint();
self.confirm_button.paint();
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
self.input.render(target);
self.cancel_button.render(target);
self.confirm_button.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area);
self.input.bounds(sink);
self.cancel_button.bounds(sink);
self.confirm_button.bounds(sink);
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for NumberInputSliderDialog {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputSliderDialog");
t.child("input", &self.input);
t.child("cancel_button", &self.cancel_button);
t.child("confirm_button", &self.confirm_button);
}
}
pub struct NumberInputSlider {
area: Rect,
touch_area: Rect,
min: u16,
max: u16,
value: u16,
}
impl NumberInputSlider {
pub fn new(min: u16, max: u16, value: u16) -> Self {
let value = value.clamp(min, max);
Self {
area: Rect::zero(),
touch_area: Rect::zero(),
min,
max,
value,
}
}
pub fn slider_eval(&mut self, pos: Point, ctx: &mut EventCtx) -> Option<u16> {
if self.touch_area.contains(pos) {
let filled = pos.x - self.area.x0;
let filled = filled.clamp(0, self.area.width());
let val_pct = (filled as u16 * 100) / self.area.width() as u16;
let val = (val_pct * (self.max - self.min)) / 100 + self.min;
if val != self.value {
self.value = val;
ctx.request_paint();
return Some(self.value);
}
}
None
}
}
impl Component for NumberInputSlider {
type Msg = u16;
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
self.touch_area = bounds.outset(Insets::new(40, 20, 40, 20)).clamp(screen());
bounds
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
if let Event::Touch(touch_event) = event {
return match touch_event {
TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx),
};
}
None
}
fn paint(&mut self) {
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
let fill_to = (val_pct as i16 * self.area.width()) / 100;
display::bar_with_text_and_fill(self.area, None, theme::FG, theme::BG, 0, fill_to as _);
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
shape::Bar::new(self.area)
.with_radius(2)
.with_thickness(2)
.with_bg(theme::BG)
.with_fg(theme::FG)
.render(target);
let inner = self.area.inset(Insets::uniform(1));
let fill_to = (val_pct as i16 * inner.width()) / 100;
let inner = inner.with_width(fill_to as _);
shape::Bar::new(inner)
.with_radius(1)
.with_bg(theme::FG)
.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area)
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for NumberInputSlider {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputSlider");
t.int("value", self.value as i64);
}
}

View File

@ -164,7 +164,8 @@ where
// Swipe has dimmed the screen, so fade back to normal backlight after the next // Swipe has dimmed the screen, so fade back to normal backlight after the next
// paint. // paint.
self.fade.set(Some(theme::BACKLIGHT_NORMAL)); self.fade
.set(Some(theme::backlight::get_backlight_normal()));
} }
fn is_cancel_visible(&self) -> bool { fn is_cancel_visible(&self) -> bool {

View File

@ -0,0 +1,74 @@
use crate::{
storage,
trezorhal::display,
ui::{
component::{Component, Event, EventCtx},
geometry::Rect,
shape::Renderer,
},
};
use super::{
super::theme,
number_input_slider::{NumberInputSliderDialog, NumberInputSliderDialogMsg},
CancelConfirmMsg,
};
pub struct SetBrightnessDialog(NumberInputSliderDialog);
impl SetBrightnessDialog {
pub fn new(current: Option<u16>) -> Self {
let current = current.unwrap_or(theme::backlight::get_backlight_normal());
Self(NumberInputSliderDialog::new(
theme::backlight::get_backlight_min(),
theme::backlight::get_backlight_max(),
current,
))
}
}
impl Component for SetBrightnessDialog {
type Msg = CancelConfirmMsg;
fn place(&mut self, bounds: Rect) -> Rect {
self.0.place(bounds)
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
match self.0.event(ctx, event) {
Some(NumberInputSliderDialogMsg::Changed(value)) => {
display::backlight(value as _);
None
}
Some(NumberInputSliderDialogMsg::Cancelled) => Some(CancelConfirmMsg::Cancelled),
Some(NumberInputSliderDialogMsg::Confirmed) => {
match storage::set_brightness(self.0.value() as _) {
Ok(_) => Some(CancelConfirmMsg::Confirmed),
Err(_) => Some(CancelConfirmMsg::Cancelled), // TODO: handle error
}
}
None => None,
}
}
fn paint(&mut self) {
self.0.paint()
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
self.0.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
self.0.bounds(sink);
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for SetBrightnessDialog {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("SetBrightnessDialog");
t.child("input", &self.0);
}
}

View File

@ -84,7 +84,8 @@ where
// Swipe has dimmed the screen, so fade back to normal backlight after the next // Swipe has dimmed the screen, so fade back to normal backlight after the next
// paint. // paint.
self.fade.set(Some(theme::BACKLIGHT_NORMAL)); self.fade
.set(Some(theme::backlight::get_backlight_normal()));
} }
fn is_horizontal(&self) -> bool { fn is_horizontal(&self) -> bool {

View File

@ -10,6 +10,7 @@ use crate::{
translations::TR, translations::TR,
trezorhal::model, trezorhal::model,
ui::{ ui::{
backlight::BACKLIGHT_LEVELS_OBJ,
component::{ component::{
base::ComponentExt, base::ComponentExt,
connect::Connect, connect::Connect,
@ -43,8 +44,8 @@ use super::{
FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput, FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput,
MnemonicKeyboard, MnemonicKeyboardMsg, PassphraseKeyboard, PassphraseKeyboardMsg, MnemonicKeyboard, MnemonicKeyboardMsg, PassphraseKeyboard, PassphraseKeyboardMsg,
PinKeyboard, PinKeyboardMsg, Progress, PromptScreen, SelectWordCount, SelectWordCountMsg, PinKeyboard, PinKeyboardMsg, Progress, PromptScreen, SelectWordCount, SelectWordCountMsg,
SimplePage, Slip39Input, StatusScreen, SwipeUpScreen, SwipeUpScreenMsg, VerticalMenu, SetBrightnessDialog, SimplePage, Slip39Input, StatusScreen, SwipeUpScreen, SwipeUpScreenMsg,
VerticalMenuChoiceMsg, VerticalMenu, VerticalMenuChoiceMsg,
}, },
flow, theme, flow, theme,
}; };
@ -247,6 +248,15 @@ where
} }
} }
impl ComponentMsgObj for SetBrightnessDialog {
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
match msg {
CancelConfirmMsg::Confirmed => Ok(CONFIRMED.as_obj()),
CancelConfirmMsg::Cancelled => Ok(CANCELLED.as_obj()),
}
}
}
impl ComponentMsgObj for Progress { impl ComponentMsgObj for Progress {
fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> { fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> {
unreachable!() unreachable!()
@ -1184,6 +1194,18 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
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_set_brightness(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let current: Option<u16> = kwargs.get(Qstr::MP_QSTR_current)?.try_into_option()?;
let obj = LayoutObj::new(Frame::centered(
TR::brightness__title.into(),
SetBrightnessDialog::new(current),
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_show_checklist(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()?;
@ -1855,6 +1877,13 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// info.""" /// info."""
Qstr::MP_QSTR_flow_request_number => obj_fn_kw!(0, flow::request_number::new_request_number).as_obj(), Qstr::MP_QSTR_flow_request_number => obj_fn_kw!(0, flow::request_number::new_request_number).as_obj(),
/// def set_brightness(
/// *,
/// current: int | None = None
/// ) -> LayoutObj[UiResult]:
/// """Show the brightness configuration dialog."""
Qstr::MP_QSTR_set_brightness => obj_fn_kw!(0, new_set_brightness).as_obj(),
/// def show_checklist( /// def show_checklist(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -18,17 +18,17 @@ pub struct ModelMercuryFeatures;
impl UIFeaturesCommon for ModelMercuryFeatures { impl UIFeaturesCommon for ModelMercuryFeatures {
fn fadein() { fn fadein() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::fade_backlight_duration(theme::BACKLIGHT_NORMAL, 150); crate::ui::display::fade_backlight_duration(theme::backlight::get_backlight_normal(), 150);
} }
fn fadeout() { fn fadeout() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::fade_backlight_duration(theme::BACKLIGHT_DIM, 150); crate::ui::display::fade_backlight_duration(theme::backlight::get_backlight_dim(), 150);
} }
fn backlight_on() { fn backlight_on() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::set_backlight(theme::BACKLIGHT_NORMAL); crate::ui::display::set_backlight(theme::backlight::get_backlight_normal());
} }
const SCREEN: Rect = constant::SCREEN; const SCREEN: Rect = constant::SCREEN;

View File

@ -0,0 +1,52 @@
#[cfg(not(feature = "bootloader"))]
use crate::storage;
// Typical backlight values.
const BACKLIGHT_NORMAL: u8 = 150;
const BACKLIGHT_LOW: u8 = 45;
const BACKLIGHT_DIM: u8 = 5;
const BACKLIGHT_NONE: u8 = 2;
const BACKLIGHT_MIN: u8 = 10;
const BACKLIGHT_MAX: u8 = 255;
#[cfg(feature = "bootloader")]
pub fn get_backlight_normal() -> u16 {
BACKLIGHT_NORMAL.into()
}
#[cfg(not(feature = "bootloader"))]
pub fn get_backlight_normal() -> u16 {
storage::get_brightness()
.unwrap_or(BACKLIGHT_NORMAL)
.clamp(BACKLIGHT_MIN, BACKLIGHT_MAX)
.into()
}
#[cfg(feature = "bootloader")]
pub fn get_backlight_low() -> u16 {
BACKLIGHT_LOW.into()
}
#[cfg(not(feature = "bootloader"))]
pub fn get_backlight_low() -> u16 {
storage::get_brightness()
.unwrap_or(BACKLIGHT_LOW)
.clamp(BACKLIGHT_MIN, BACKLIGHT_LOW)
.into()
}
pub fn get_backlight_dim() -> u16 {
BACKLIGHT_DIM.into()
}
pub fn get_backlight_none() -> u16 {
BACKLIGHT_NONE.into()
}
pub fn get_backlight_max() -> u16 {
BACKLIGHT_MAX.into()
}
pub fn get_backlight_min() -> u16 {
BACKLIGHT_MIN.into()
}

View File

@ -1,5 +1,7 @@
pub mod bootloader; pub mod bootloader;
pub mod backlight;
use crate::{ use crate::{
time::Duration, time::Duration,
ui::{ ui::{
@ -18,13 +20,6 @@ use num_traits::FromPrimitive;
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
// Typical backlight values.
pub const BACKLIGHT_NORMAL: u16 = 150;
pub const BACKLIGHT_LOW: u16 = 45;
pub const BACKLIGHT_DIM: u16 = 5;
pub const BACKLIGHT_NONE: u16 = 2;
pub const BACKLIGHT_MAX: u16 = 255;
// Color palette. // Color palette.
pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF); pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF);
pub const BLACK: Color = Color::rgb(0, 0, 0); pub const BLACK: Color = Color::rgb(0, 0, 0);

View File

@ -16,6 +16,7 @@ use super::{
bl_confirm::{Confirm, ConfirmTitle}, bl_confirm::{Confirm, ConfirmTitle},
Button, ResultScreen, WelcomeScreen, Button, ResultScreen, WelcomeScreen,
}, },
theme,
theme::{ theme::{
bootloader::{ bootloader::{
button_bld, button_bld_menu, button_confirm, button_wipe_cancel, button_wipe_confirm, button_bld, button_bld_menu, button_confirm, button_wipe_cancel, button_wipe_confirm,
@ -23,7 +24,7 @@ use super::{
FIRE40, RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL, FIRE40, RESULT_FW_INSTALL, RESULT_INITIAL, RESULT_WIPE, TEXT_BOLD, TEXT_NORMAL,
TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24, TEXT_WIPE_BOLD, TEXT_WIPE_NORMAL, WARNING40, WELCOME_COLOR, X24,
}, },
BACKLIGHT_NORMAL, FG, FG,
}, },
ModelTTFeatures, ModelTTFeatures,
}; };
@ -335,7 +336,7 @@ impl UIFeaturesBootloader for ModelTTFeatures {
if fading { if fading {
Self::fadein(); Self::fadein();
} else { } else {
display::set_backlight(BACKLIGHT_NORMAL); display::set_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -209,7 +209,7 @@ where
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }
@ -239,7 +239,7 @@ where
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -297,7 +297,7 @@ impl Component for PassphraseKeyboard {
} }
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }
@ -311,7 +311,7 @@ impl Component for PassphraseKeyboard {
} }
if self.fade.take() { if self.fade.take() {
// Note that this is blocking and takes some time. // Note that this is blocking and takes some time.
display::fade_backlight(theme::BACKLIGHT_NORMAL); display::fade_backlight(theme::backlight::get_backlight_normal());
} }
} }

View File

@ -16,11 +16,13 @@ mod keyboard;
mod loader; mod loader;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
mod number_input; mod number_input;
pub mod number_input_slider;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
mod page; mod page;
mod progress; mod progress;
mod result; mod result;
mod scroll; mod scroll;
mod set_brightness;
mod simple_page; mod simple_page;
mod swipe; mod swipe;
mod welcome_screen; mod welcome_screen;
@ -50,11 +52,13 @@ pub use keyboard::{
pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet}; pub use loader::{Loader, LoaderMsg, LoaderStyle, LoaderStyleSheet};
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
pub use number_input::{NumberInputDialog, NumberInputDialogMsg}; pub use number_input::{NumberInputDialog, NumberInputDialogMsg};
pub use number_input_slider::NumberInputSliderDialog;
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
pub use page::ButtonPage; pub use page::ButtonPage;
pub use progress::Progress; pub use progress::Progress;
pub use result::{ResultFooter, ResultScreen, ResultStyle}; pub use result::{ResultFooter, ResultScreen, ResultStyle};
pub use scroll::ScrollBar; pub use scroll::ScrollBar;
pub use set_brightness::SetBrightnessDialog;
pub use simple_page::SimplePage; pub use simple_page::SimplePage;
pub use swipe::{Swipe, SwipeDirection}; pub use swipe::{Swipe, SwipeDirection};
pub use welcome_screen::WelcomeScreen; pub use welcome_screen::WelcomeScreen;

View File

@ -0,0 +1,204 @@
use crate::ui::{
component::{base::ComponentExt, Child, Component, Event, EventCtx},
constant::screen,
display,
event::TouchEvent,
geometry::{Grid, Insets, Point, Rect},
shape::{self, Renderer},
};
use super::{theme, Button, ButtonMsg};
pub enum NumberInputSliderDialogMsg {
Changed(u16),
Confirmed,
Cancelled,
}
pub struct NumberInputSliderDialog {
area: Rect,
input: Child<NumberInputSlider>,
cancel_button: Child<Button>,
confirm_button: Child<Button>,
}
impl NumberInputSliderDialog {
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
Self {
area: Rect::zero(),
input: NumberInputSlider::new(min, max, init_value).into_child(),
cancel_button: Button::with_text("CANCEL".into())
.styled(theme::button_cancel())
.into_child(),
confirm_button: Button::with_text("CONFIRM".into())
.styled(theme::button_confirm())
.into_child(),
}
}
pub fn value(&self) -> u16 {
self.input.inner().value
}
}
impl Component for NumberInputSliderDialog {
type Msg = NumberInputSliderDialogMsg;
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
let button_height = theme::BUTTON_HEIGHT;
let content_area = self.area.inset(Insets::top(2 * theme::BUTTON_SPACING));
let (_, content_area) = content_area.split_top(30);
let (input_area, _) = content_area.split_top(15);
let (_, button_area) = content_area.split_bottom(button_height);
let grid = Grid::new(button_area, 1, 2).with_spacing(theme::KEYBOARD_SPACING);
self.input.place(input_area.inset(Insets::sides(20)));
self.cancel_button.place(grid.row_col(0, 0));
self.confirm_button.place(grid.row_col(0, 1));
bounds
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
if let Some(value) = self.input.event(ctx, event) {
return Some(Self::Msg::Changed(value));
}
if let Some(ButtonMsg::Clicked) = self.cancel_button.event(ctx, event) {
return Some(Self::Msg::Cancelled);
}
if let Some(ButtonMsg::Clicked) = self.confirm_button.event(ctx, event) {
return Some(Self::Msg::Confirmed);
};
None
}
fn paint(&mut self) {
self.input.paint();
self.cancel_button.paint();
self.confirm_button.paint();
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
self.input.render(target);
self.cancel_button.render(target);
self.confirm_button.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area);
self.input.bounds(sink);
self.cancel_button.bounds(sink);
self.confirm_button.bounds(sink);
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for NumberInputSliderDialog {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputSliderDialog");
t.child("input", &self.input);
t.child("cancel_button", &self.cancel_button);
t.child("confirm_button", &self.confirm_button);
}
}
pub struct NumberInputSlider {
area: Rect,
touch_area: Rect,
min: u16,
max: u16,
value: u16,
}
impl NumberInputSlider {
pub fn new(min: u16, max: u16, value: u16) -> Self {
let value = value.clamp(min, max);
Self {
area: Rect::zero(),
touch_area: Rect::zero(),
min,
max,
value,
}
}
pub fn slider_eval(&mut self, pos: Point, ctx: &mut EventCtx) -> Option<u16> {
if self.touch_area.contains(pos) {
let filled = pos.x - self.area.x0;
let filled = filled.clamp(0, self.area.width());
let val_pct = (filled as u16 * 100) / self.area.width() as u16;
let val = (val_pct * (self.max - self.min)) / 100 + self.min;
if val != self.value {
self.value = val;
ctx.request_paint();
return Some(self.value);
}
}
None
}
}
impl Component for NumberInputSlider {
type Msg = u16;
fn place(&mut self, bounds: Rect) -> Rect {
self.area = bounds;
self.touch_area = bounds.outset(Insets::new(40, 20, 40, 20)).clamp(screen());
bounds
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
if let Event::Touch(touch_event) = event {
return match touch_event {
TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx),
};
}
None
}
fn paint(&mut self) {
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
let fill_to = (val_pct as i16 * self.area.width()) / 100;
display::bar_with_text_and_fill(self.area, None, theme::FG, theme::BG, 0, fill_to as _);
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
let val_pct = (100 * (self.value - self.min)) / (self.max - self.min);
shape::Bar::new(self.area)
.with_radius(2)
.with_thickness(2)
.with_bg(theme::BG)
.with_fg(theme::FG)
.render(target);
let inner = self.area.inset(Insets::uniform(1));
let fill_to = (val_pct as i16 * inner.width()) / 100;
let inner = inner.with_width(fill_to as _);
shape::Bar::new(inner)
.with_radius(1)
.with_bg(theme::FG)
.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
sink(self.area)
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for NumberInputSlider {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("NumberInputSlider");
t.int("value", self.value as i64);
}
}

View File

@ -163,7 +163,8 @@ where
// Swipe has dimmed the screen, so fade back to normal backlight after the next // Swipe has dimmed the screen, so fade back to normal backlight after the next
// paint. // paint.
self.fade.set(Some(theme::BACKLIGHT_NORMAL)); self.fade
.set(Some(theme::backlight::get_backlight_normal()));
} }
fn is_cancel_visible(&self) -> bool { fn is_cancel_visible(&self) -> bool {

View File

@ -0,0 +1,74 @@
use crate::{
storage,
trezorhal::display,
ui::{
component::{Component, Event, EventCtx},
geometry::Rect,
shape::Renderer,
},
};
use super::{
super::theme,
number_input_slider::{NumberInputSliderDialog, NumberInputSliderDialogMsg},
CancelConfirmMsg,
};
pub struct SetBrightnessDialog(NumberInputSliderDialog);
impl SetBrightnessDialog {
pub fn new(current: Option<u16>) -> Self {
let current = current.unwrap_or(theme::backlight::get_backlight_normal());
Self(NumberInputSliderDialog::new(
theme::backlight::get_backlight_min(),
theme::backlight::get_backlight_max(),
current,
))
}
}
impl Component for SetBrightnessDialog {
type Msg = CancelConfirmMsg;
fn place(&mut self, bounds: Rect) -> Rect {
self.0.place(bounds)
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
match self.0.event(ctx, event) {
Some(NumberInputSliderDialogMsg::Changed(value)) => {
display::backlight(value as _);
None
}
Some(NumberInputSliderDialogMsg::Cancelled) => Some(CancelConfirmMsg::Cancelled),
Some(NumberInputSliderDialogMsg::Confirmed) => {
match storage::set_brightness(self.0.value() as _) {
Ok(_) => Some(CancelConfirmMsg::Confirmed),
Err(_) => Some(CancelConfirmMsg::Cancelled), // TODO: handle error
}
}
None => None,
}
}
fn paint(&mut self) {
self.0.paint()
}
fn render<'s>(&self, target: &mut impl Renderer<'s>) {
self.0.render(target);
}
#[cfg(feature = "ui_bounds")]
fn bounds(&self, sink: &mut dyn FnMut(Rect)) {
self.0.bounds(sink);
}
}
#[cfg(feature = "ui_debug")]
impl crate::trace::Trace for SetBrightnessDialog {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("SetBrightnessDialog");
t.child("input", &self.0);
}
}

View File

@ -81,7 +81,8 @@ where
// Swipe has dimmed the screen, so fade back to normal backlight after the next // Swipe has dimmed the screen, so fade back to normal backlight after the next
// paint. // paint.
self.fade.set(Some(theme::BACKLIGHT_NORMAL)); self.fade
.set(Some(theme::backlight::get_backlight_normal()));
} }
fn is_horizontal(&self) -> bool { fn is_horizontal(&self) -> bool {

View File

@ -3,11 +3,10 @@ use crate::ui::{
display, display,
event::TouchEvent, event::TouchEvent,
geometry::{Point, Rect}, geometry::{Point, Rect},
model_tt::theme::backlight,
shape::Renderer, shape::Renderer,
}; };
use super::theme;
pub enum SwipeDirection { pub enum SwipeDirection {
Up, Up,
Down, Down,
@ -37,8 +36,8 @@ impl Swipe {
allow_down: false, allow_down: false,
allow_left: false, allow_left: false,
allow_right: false, allow_right: false,
backlight_start: theme::BACKLIGHT_NORMAL, backlight_start: backlight::get_backlight_normal(),
backlight_end: theme::BACKLIGHT_NONE, backlight_end: backlight::get_backlight_none(),
origin: None, origin: None,
} }
} }

View File

@ -44,7 +44,8 @@ use super::{
FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput, FidoMsg, Frame, FrameMsg, Homescreen, HomescreenMsg, IconDialog, Lockscreen, MnemonicInput,
MnemonicKeyboard, MnemonicKeyboardMsg, NumberInputDialog, NumberInputDialogMsg, MnemonicKeyboard, MnemonicKeyboardMsg, NumberInputDialog, NumberInputDialogMsg,
PassphraseKeyboard, PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress, PassphraseKeyboard, PassphraseKeyboardMsg, PinKeyboard, PinKeyboardMsg, Progress,
SelectWordCount, SelectWordCountMsg, SelectWordMsg, SimplePage, Slip39Input, SelectWordCount, SelectWordCountMsg, SelectWordMsg, SetBrightnessDialog, SimplePage,
Slip39Input,
}, },
theme, theme,
}; };
@ -220,6 +221,15 @@ where
} }
} }
impl ComponentMsgObj for SetBrightnessDialog {
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
match msg {
CancelConfirmMsg::Cancelled => Ok(CANCELLED.as_obj()),
CancelConfirmMsg::Confirmed => Ok(CONFIRMED.as_obj()),
}
}
}
impl ComponentMsgObj for Progress { impl ComponentMsgObj for Progress {
fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> { fn msg_try_into_obj(&self, _msg: Self::Msg) -> Result<Obj, Error> {
unreachable!() unreachable!()
@ -1293,6 +1303,19 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut 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_set_brightness(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let current: Option<u16> = kwargs.get(Qstr::MP_QSTR_current)?.try_into_option()?;
let obj = LayoutObj::new(Frame::centered(
theme::label_title(),
TR::brightness__title.into(),
SetBrightnessDialog::new(current),
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_show_checklist(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_show_checklist(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()?;
@ -1990,6 +2013,13 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Number input with + and - buttons, description, and info button.""" /// """Number input with + and - buttons, description, and info button."""
Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(), Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(),
/// def set_brightness(
/// *,
/// current: int | None = None
/// ) -> LayoutObj[UiResult]:
/// """Show the brightness configuration dialog."""
Qstr::MP_QSTR_set_brightness => obj_fn_kw!(0, new_set_brightness).as_obj(),
/// def show_checklist( /// def show_checklist(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -6,6 +6,9 @@ pub mod component;
pub mod constant; pub mod constant;
pub mod theme; pub mod theme;
#[cfg(feature = "backlight")]
use crate::ui::model_tt::theme::backlight;
#[cfg(feature = "micropython")] #[cfg(feature = "micropython")]
pub mod layout; pub mod layout;
@ -19,17 +22,17 @@ pub struct ModelTTFeatures;
impl UIFeaturesCommon for ModelTTFeatures { impl UIFeaturesCommon for ModelTTFeatures {
fn fadein() { fn fadein() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::fade_backlight_duration(theme::BACKLIGHT_NORMAL, 150); crate::ui::display::fade_backlight_duration(backlight::get_backlight_normal(), 150);
} }
fn fadeout() { fn fadeout() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::fade_backlight_duration(theme::BACKLIGHT_DIM, 150); crate::ui::display::fade_backlight_duration(backlight::get_backlight_normal(), 150);
} }
fn backlight_on() { fn backlight_on() {
#[cfg(feature = "backlight")] #[cfg(feature = "backlight")]
crate::ui::display::set_backlight(theme::BACKLIGHT_NORMAL); crate::ui::display::set_backlight(backlight::get_backlight_normal());
} }
const SCREEN: Rect = constant::SCREEN; const SCREEN: Rect = constant::SCREEN;

View File

@ -0,0 +1,52 @@
#[cfg(not(feature = "bootloader"))]
use crate::storage;
// Typical backlight values.
const BACKLIGHT_NORMAL: u8 = 150;
const BACKLIGHT_LOW: u8 = 45;
const BACKLIGHT_DIM: u8 = 5;
const BACKLIGHT_NONE: u8 = 2;
const BACKLIGHT_MIN: u8 = 10;
const BACKLIGHT_MAX: u8 = 255;
#[cfg(feature = "bootloader")]
pub fn get_backlight_normal() -> u16 {
BACKLIGHT_NORMAL.into()
}
#[cfg(not(feature = "bootloader"))]
pub fn get_backlight_normal() -> u16 {
storage::get_brightness()
.unwrap_or(BACKLIGHT_NORMAL)
.clamp(BACKLIGHT_MIN, BACKLIGHT_MAX)
.into()
}
#[cfg(feature = "bootloader")]
pub fn get_backlight_low() -> u16 {
BACKLIGHT_LOW.into()
}
#[cfg(not(feature = "bootloader"))]
pub fn get_backlight_low() -> u16 {
storage::get_brightness()
.unwrap_or(BACKLIGHT_LOW)
.clamp(BACKLIGHT_MIN, BACKLIGHT_LOW)
.into()
}
pub fn get_backlight_dim() -> u16 {
BACKLIGHT_DIM.into()
}
pub fn get_backlight_none() -> u16 {
BACKLIGHT_NONE.into()
}
pub fn get_backlight_max() -> u16 {
BACKLIGHT_MAX.into()
}
pub fn get_backlight_min() -> u16 {
BACKLIGHT_MIN.into()
}

View File

@ -1,3 +1,4 @@
pub mod backlight;
pub mod bootloader; pub mod bootloader;
use crate::{ use crate::{
@ -18,13 +19,6 @@ use num_traits::FromPrimitive;
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500); pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
// Typical backlight values.
pub const BACKLIGHT_NORMAL: u16 = 150;
pub const BACKLIGHT_LOW: u16 = 45;
pub const BACKLIGHT_DIM: u16 = 5;
pub const BACKLIGHT_NONE: u16 = 2;
pub const BACKLIGHT_MAX: u16 = 255;
// Color palette. // Color palette.
pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF); pub const WHITE: Color = Color::rgb(0xFF, 0xFF, 0xFF);
pub const BLACK: Color = Color::rgb(0, 0, 0); pub const BLACK: Color = Color::rgb(0, 0, 0);

View File

@ -4,9 +4,11 @@
#include STM32_HAL_H #include STM32_HAL_H
#include TREZOR_BOARD #include TREZOR_BOARD
#define TIM_FREQ 1000000 #define TIM_FREQ 10000000
#define LED_PWM_PRESCALER (SystemCoreClock / TIM_FREQ - 1) // 1 MHz #define LED_PWM_PRESCALER (SystemCoreClock / TIM_FREQ - 1)
#define LED_PWM_PRESCALER_SLOW (SystemCoreClock / 1000000 - 1) // 1 MHz
#define LED_PWM_TIM_PERIOD (TIM_FREQ / BACKLIGHT_PWM_FREQ) #define LED_PWM_TIM_PERIOD (TIM_FREQ / BACKLIGHT_PWM_FREQ)
@ -16,6 +18,30 @@ static int pwm_period = 0;
int backlight_pwm_set(int val) { int backlight_pwm_set(int val) {
if (BACKLIGHT != val && val >= 0 && val <= 255) { if (BACKLIGHT != val && val >= 0 && val <= 255) {
// TPS61043 goes to shutdown when duty cycle is 0 (after 32ms),
// so we need to set GPIO to high for at least 500us
// to wake it up.
if (BACKLIGHT_PWM_TIM->BACKLIGHT_PWM_TIM_CCR == 0) {
GPIO_InitTypeDef GPIO_InitStructure = {0};
HAL_GPIO_WritePin(BACKLIGHT_PWM_PORT, BACKLIGHT_PWM_PIN, GPIO_PIN_SET);
// LCD_PWM/PA7 (backlight control)
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Pin = BACKLIGHT_PWM_PIN;
HAL_GPIO_Init(BACKLIGHT_PWM_PORT, &GPIO_InitStructure);
hal_delay_us(500);
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = BACKLIGHT_PWM_TIM_AF;
GPIO_InitStructure.Pin = BACKLIGHT_PWM_PIN;
HAL_GPIO_Init(BACKLIGHT_PWM_PORT, &GPIO_InitStructure);
}
BACKLIGHT = val; BACKLIGHT = val;
BACKLIGHT_PWM_TIM->CCR1 = (pwm_period * val) / 255; BACKLIGHT_PWM_TIM->CCR1 = (pwm_period * val) / 255;
} }
@ -157,6 +183,7 @@ void backlight_pwm_reinit(void) {
BACKLIGHT = prev_val; BACKLIGHT = prev_val;
pwm_period = LED_PWM_TIM_PERIOD; pwm_period = LED_PWM_TIM_PERIOD;
BACKLIGHT_PWM_TIM->PSC = LED_PWM_PRESCALER;
BACKLIGHT_PWM_TIM->CR1 |= TIM_CR1_ARPE; BACKLIGHT_PWM_TIM->CR1 |= TIM_CR1_ARPE;
BACKLIGHT_PWM_TIM->CR2 |= TIM_CR2_CCPC; BACKLIGHT_PWM_TIM->CR2 |= TIM_CR2_CCPC;
BACKLIGHT_PWM_TIM->BACKLIGHT_PWM_TIM_CCR = (pwm_period * prev_val) / 255; BACKLIGHT_PWM_TIM->BACKLIGHT_PWM_TIM_CCR = (pwm_period * prev_val) / 255;
@ -176,6 +203,7 @@ void backlight_pwm_set_slow(void) {
prev_val = prev_val > 255 ? 255 : prev_val; prev_val = prev_val > 255 ? 255 : prev_val;
pwm_period = LED_PWM_SLOW_TIM_PERIOD; pwm_period = LED_PWM_SLOW_TIM_PERIOD;
BACKLIGHT_PWM_TIM->PSC = LED_PWM_PRESCALER_SLOW;
BACKLIGHT_PWM_TIM->CR1 |= TIM_CR1_ARPE; BACKLIGHT_PWM_TIM->CR1 |= TIM_CR1_ARPE;
BACKLIGHT_PWM_TIM->CR2 |= TIM_CR2_CCPC; BACKLIGHT_PWM_TIM->CR2 |= TIM_CR2_CCPC;
BACKLIGHT_PWM_TIM->ARR = LED_PWM_SLOW_TIM_PERIOD - 1; BACKLIGHT_PWM_TIM->ARR = LED_PWM_SLOW_TIM_PERIOD - 1;

View File

@ -421,6 +421,14 @@ def flow_request_number(
info.""" info."""
# rust/src/ui/model_mercury/layout.rs
def set_brightness(
*,
current: int | None = None
) -> LayoutObj[UiResult]:
"""Show the brightness configuration dialog."""
# rust/src/ui/model_mercury/layout.rs # rust/src/ui/model_mercury/layout.rs
def show_checklist( def show_checklist(
*, *,
@ -1040,6 +1048,16 @@ def confirm_firmware_update(
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def show_wait_text(message: str, /) -> None: def show_wait_text(message: str, /) -> None:
"""Show single-line text in the middle of the screen.""" """Show single-line text in the middle of the screen."""
# rust/src/ui/model_tr/layout.rs
class BacklightLevels:
"""Backlight levels. Values dynamically update based on user settings."""
MAX: ClassVar[int]
NORMAL: ClassVar[int]
LOW: ClassVar[int]
DIM: ClassVar[int]
NONE: ClassVar[int]
from trezor import utils from trezor import utils
T = TypeVar("T") T = TypeVar("T")
@ -1453,6 +1471,14 @@ def request_number(
"""Number input with + and - buttons, description, and info button.""" """Number input with + and - buttons, description, and info button."""
# rust/src/ui/model_tt/layout.rs
def set_brightness(
*,
current: int | None = None
) -> LayoutObj[UiResult]:
"""Show the brightness configuration dialog."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_checklist( def show_checklist(
*, *,

View File

@ -79,6 +79,7 @@ class TR:
bitcoin__unverified_external_inputs: str = "The transaction contains unverified external inputs." bitcoin__unverified_external_inputs: str = "The transaction contains unverified external inputs."
bitcoin__valid_signature: str = "The signature is valid." bitcoin__valid_signature: str = "The signature is valid."
bitcoin__voting_rights: str = "Voting rights to:" bitcoin__voting_rights: str = "Voting rights to:"
brightness__title: str = "Set brightness"
buttons__abort: str = "Abort" buttons__abort: str = "Abort"
buttons__access: str = "Access" buttons__access: str = "Access"
buttons__again: str = "Again" buttons__again: str = "Again"

View File

@ -357,6 +357,8 @@ apps.management.reset_device.layout
import apps.management.reset_device.layout import apps.management.reset_device.layout
apps.management.sd_protect apps.management.sd_protect
import apps.management.sd_protect import apps.management.sd_protect
apps.management.set_brightness
import apps.management.set_brightness
apps.management.set_u2f_counter apps.management.set_u2f_counter
import apps.management.set_u2f_counter import apps.management.set_u2f_counter
apps.management.show_tutorial apps.management.show_tutorial

View File

@ -135,6 +135,9 @@ def get_features() -> Features:
] ]
) )
if utils.USE_BACKLIGHT:
f.capabilities.append(Capability.Brightness)
# Only some models are capable of SD card # Only some models are capable of SD card
if utils.USE_SD_CARD: if utils.USE_SD_CARD:
from trezor import sdcard from trezor import sdcard
@ -434,7 +437,7 @@ def reload_settings_from_storage() -> None:
) )
wire.EXPERIMENTAL_ENABLED = storage_device.get_experimental_features() wire.EXPERIMENTAL_ENABLED = storage_device.get_experimental_features()
if ui.display.orientation() != storage_device.get_rotation(): if ui.display.orientation() != storage_device.get_rotation():
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
ui.display.orientation(storage_device.get_rotation()) ui.display.orientation(storage_device.get_rotation())

View File

@ -0,0 +1,17 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from trezor.messages import SetBrightness, Success
async def set_brightness(_msg: SetBrightness) -> Success:
import storage.device as storage_device
from trezor.messages import Success
from trezor.ui.layouts import set_brightness
from trezor.wire import NotInitialized
if not storage_device.is_initialized():
raise NotInitialized("Device is not initialized")
await set_brightness()
return Success(message="Settings applied")

View File

@ -58,6 +58,9 @@ def _find_message_handler_module(msg_type: int) -> str:
if utils.INTERNAL_MODEL in ("T2B1",) and msg_type == MessageType.ShowDeviceTutorial: if utils.INTERNAL_MODEL in ("T2B1",) and msg_type == MessageType.ShowDeviceTutorial:
return "apps.management.show_tutorial" return "apps.management.show_tutorial"
if utils.USE_BACKLIGHT and msg_type == MessageType.SetBrightness:
return "apps.management.set_brightness"
if utils.USE_SD_CARD and msg_type == MessageType.SdProtect: if utils.USE_SD_CARD and msg_type == MessageType.SdProtect:
return "apps.management.sd_protect" return "apps.management.sd_protect"

View File

@ -49,7 +49,7 @@ async def bootscreen() -> None:
if can_lock_device(): if can_lock_device():
enforce_welcome_screen_duration() enforce_welcome_screen_duration()
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
ui.display.orientation(storage.device.get_rotation()) ui.display.orientation(storage.device.get_rotation())
await lockscreen await lockscreen
await verify_user_pin() await verify_user_pin()
@ -64,7 +64,7 @@ async def bootscreen() -> None:
if rotation != ui.display.orientation(): if rotation != ui.display.orientation():
# there is a slight delay before next screen is shown, # there is a slight delay before next screen is shown,
# so we don't fade unless there is a change of orientation # so we don't fade unless there is a change of orientation
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
ui.display.orientation(rotation) ui.display.orientation(rotation)
allow_all_loader_messages() allow_all_loader_messages()
return return

View File

@ -49,12 +49,12 @@ def get_bool(app: int, key: int, public: bool = False) -> bool:
return get(app, key, public) == _TRUE_BYTE return get(app, key, public) == _TRUE_BYTE
def set_uint8(app: int, key: int, val: int) -> None: def set_uint8(app: int, key: int, val: int, public: bool = False) -> None:
set(app, key, val.to_bytes(1, "big")) set(app, key, val.to_bytes(1, "big"), public)
def get_uint8(app: int, key: int) -> int | None: def get_uint8(app: int, key: int, public: bool = False) -> int | None:
val = get(app, key) val = get(app, key, public)
if not val: if not val:
return None return None
return int.from_bytes(val, "big") return int.from_bytes(val, "big")

View File

@ -36,6 +36,8 @@ INITIALIZED = const(0x13) # bool (0x01 or empty)
_SAFETY_CHECK_LEVEL = const(0x14) # int _SAFETY_CHECK_LEVEL = const(0x14) # int
_EXPERIMENTAL_FEATURES = const(0x15) # bool (0x01 or empty) _EXPERIMENTAL_FEATURES = const(0x15) # bool (0x01 or empty)
_HIDE_PASSPHRASE_FROM_HOST = const(0x16) # bool (0x01 or empty) _HIDE_PASSPHRASE_FROM_HOST = const(0x16) # bool (0x01 or empty)
# unused from python:
# _BRIGHTNESS = const(0x18) # int
if utils.USE_THP: if utils.USE_THP:
_DEVICE_SECRET = const(0x17) # bytes _DEVICE_SECRET = const(0x17) # bytes

View File

@ -10,6 +10,7 @@ Shamir = 15
ShamirGroups = 16 ShamirGroups = 16
PassphraseEntry = 17 PassphraseEntry = 17
Translations = 19 Translations = 19
Brightness = 20
if not utils.BITCOIN_ONLY: if not utils.BITCOIN_ONLY:
Bitcoin_like = 2 Bitcoin_like = 2
Binance = 3 Binance = 3

View File

@ -53,6 +53,7 @@ AuthenticityProof = 98
ChangeLanguage = 990 ChangeLanguage = 990
TranslationDataRequest = 991 TranslationDataRequest = 991
TranslationDataAck = 992 TranslationDataAck = 992
SetBrightness = 993
FirmwareErase = 6 FirmwareErase = 6
FirmwareUpload = 7 FirmwareUpload = 7
FirmwareRequest = 8 FirmwareRequest = 8

View File

@ -70,6 +70,7 @@ if TYPE_CHECKING:
ChangeLanguage = 990 ChangeLanguage = 990
TranslationDataRequest = 991 TranslationDataRequest = 991
TranslationDataAck = 992 TranslationDataAck = 992
SetBrightness = 993
SetU2FCounter = 63 SetU2FCounter = 63
GetNextU2FCounter = 80 GetNextU2FCounter = 80
NextU2FCounter = 81 NextU2FCounter = 81
@ -459,6 +460,7 @@ if TYPE_CHECKING:
PassphraseEntry = 17 PassphraseEntry = 17
Solana = 18 Solana = 18
Translations = 19 Translations = 19
Brightness = 20
class SdProtectOperationType(IntEnum): class SdProtectOperationType(IntEnum):
DISABLE = 0 DISABLE = 0

View File

@ -2776,6 +2776,20 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["UnlockBootloader"]: def is_type_of(cls, msg: Any) -> TypeGuard["UnlockBootloader"]:
return isinstance(msg, cls) return isinstance(msg, cls)
class SetBrightness(protobuf.MessageType):
value: "int | None"
def __init__(
self,
*,
value: "int | None" = None,
) -> None:
pass
@classmethod
def is_type_of(cls, msg: Any) -> TypeGuard["SetBrightness"]:
return isinstance(msg, cls)
class Slip39Group(protobuf.MessageType): class Slip39Group(protobuf.MessageType):
member_threshold: "int" member_threshold: "int"
member_count: "int" member_count: "int"

View File

@ -62,12 +62,12 @@ async def _alert(count: int) -> None:
long_sleep = loop.sleep(80) long_sleep = loop.sleep(80)
for i in range(count * 2): for i in range(count * 2):
if i % 2 == 0: if i % 2 == 0:
display.backlight(style.BACKLIGHT_MAX) display.backlight(style.get_backlight_max())
await short_sleep await short_sleep
else: else:
display.backlight(style.BACKLIGHT_DIM) display.backlight(style.get_backlight_dim())
await long_sleep await long_sleep
display.backlight(style.BACKLIGHT_NORMAL) display.backlight(style.get_backlight_normal())
global _alert_in_progress global _alert_in_progress
_alert_in_progress = False _alert_in_progress = False

View File

@ -30,7 +30,6 @@ if __debug__:
class RustLayout(ui.Layout): class RustLayout(ui.Layout):
BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
def __init__(self, layout: Any): def __init__(self, layout: Any):
@ -39,6 +38,7 @@ class RustLayout(ui.Layout):
self.timer = loop.Timer() self.timer = loop.Timer()
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
self._send_button_request() self._send_button_request()
self.backlight_level = ui.style.get_backlight_normal()
def set_timer(self, token: int, deadline: int) -> None: def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token) self.timer.schedule(deadline, token)
@ -187,7 +187,7 @@ class RustLayout(ui.Layout):
) )
def _first_paint(self) -> None: def _first_paint(self) -> None:
ui.backlight_fade(ui.style.BACKLIGHT_NONE) ui.backlight_fade(ui.style.get_backlight_none())
self._paint() self._paint()
if __debug__ and self.should_notify_layout_change: if __debug__ and self.should_notify_layout_change:
@ -210,7 +210,7 @@ class RustLayout(ui.Layout):
notify_layout_change(self, event_id) notify_layout_change(self, event_id)
# Turn the brightness on again. # Turn the brightness on again.
ui.backlight_fade(self.BACKLIGHT_LEVEL) ui.backlight_fade(self.backlight_level)
def handle_input_and_rendering(self) -> loop.Task: def handle_input_and_rendering(self) -> loop.Task:
from trezor import workflow from trezor import workflow
@ -263,10 +263,10 @@ def draw_simple(layout: Any) -> None:
raise RuntimeError raise RuntimeError
layout.attach_timer_fn(dummy_set_timer) layout.attach_timer_fn(dummy_set_timer)
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
layout.paint() layout.paint()
ui.refresh() ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) ui.backlight_fade(ui.style.get_backlight_normal())
async def raise_if_not_confirmed( async def raise_if_not_confirmed(
@ -1459,3 +1459,11 @@ async def confirm_firmware_update(description: str, fingerprint: str) -> None:
BR_TYPE_OTHER, BR_TYPE_OTHER,
) )
) )
async def set_brightness(current: int | None = None) -> None:
await interact(
RustLayout(trezorui2.set_brightness(current=current)),
"set_brightness",
BR_TYPE_OTHER,
)

View File

@ -85,7 +85,6 @@ class Homescreen(HomescreenBase):
class Lockscreen(HomescreenBase): class Lockscreen(HomescreenBase):
RENDER_INDICATOR = storage_cache.LOCKSCREEN_ON RENDER_INDICATOR = storage_cache.LOCKSCREEN_ON
BACKLIGHT_LEVEL = ui.style.BACKLIGHT_LOW
def __init__( def __init__(
self, self,
@ -94,8 +93,9 @@ class Lockscreen(HomescreenBase):
coinjoin_authorized: bool = False, coinjoin_authorized: bool = False,
) -> None: ) -> None:
self.bootscreen = bootscreen self.bootscreen = bootscreen
self.backlight_level = ui.style.get_backlight_low()
if bootscreen: if bootscreen:
self.BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL self.backlight_level = ui.style.get_backlight_normal()
skip = ( skip = (
not bootscreen and storage_cache.homescreen_shown is self.RENDER_INDICATOR not bootscreen and storage_cache.homescreen_shown is self.RENDER_INDICATOR

View File

@ -15,11 +15,11 @@ class RustProgress:
layout: Any, layout: Any,
): ):
self.layout = layout self.layout = layout
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
self.layout.paint() self.layout.paint()
ui.refresh() ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) ui.backlight_fade(ui.style.get_backlight_normal())
def set_timer(self, token: int, deadline: int) -> None: def set_timer(self, token: int, deadline: int) -> None:
raise RuntimeError # progress layouts should not set timers raise RuntimeError # progress layouts should not set timers

View File

@ -34,11 +34,11 @@ class RustProgress:
layout: Any, layout: Any,
): ):
self.layout = layout self.layout = layout
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
self.layout.paint() self.layout.paint()
ui.refresh() ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) ui.backlight_fade(ui.style.get_backlight_normal())
def set_timer(self, token: int, deadline: int) -> None: def set_timer(self, token: int, deadline: int) -> None:
raise RuntimeError # progress layouts should not set timers raise RuntimeError # progress layouts should not set timers

View File

@ -36,7 +36,6 @@ if __debug__:
class RustLayout(LayoutParentType[T]): class RustLayout(LayoutParentType[T]):
BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
def __init__(self, layout: trezorui2.LayoutObj[T]): def __init__(self, layout: trezorui2.LayoutObj[T]):
@ -45,6 +44,7 @@ class RustLayout(LayoutParentType[T]):
self.timer = loop.Timer() self.timer = loop.Timer()
self.layout.attach_timer_fn(self.set_timer) self.layout.attach_timer_fn(self.set_timer)
self._send_button_request() self._send_button_request()
self.backlight_level = ui.style.get_backlight_normal()
def set_timer(self, token: int, deadline: int) -> None: def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token) self.timer.schedule(deadline, token)
@ -193,7 +193,7 @@ class RustLayout(LayoutParentType[T]):
) )
def _first_paint(self) -> None: def _first_paint(self) -> None:
ui.backlight_fade(ui.style.BACKLIGHT_NONE) ui.backlight_fade(ui.style.get_backlight_none())
self._paint() self._paint()
if __debug__ and self.should_notify_layout_change: if __debug__ and self.should_notify_layout_change:
@ -216,7 +216,7 @@ class RustLayout(LayoutParentType[T]):
notify_layout_change(self, event_id) notify_layout_change(self, event_id)
# Turn the brightness on again. # Turn the brightness on again.
ui.backlight_fade(self.BACKLIGHT_LEVEL) ui.backlight_fade(self.backlight_level)
def handle_input_and_rendering(self) -> loop.Task: def handle_input_and_rendering(self) -> loop.Task:
from trezor import workflow from trezor import workflow
@ -269,10 +269,10 @@ def draw_simple(layout: trezorui2.LayoutObj[Any]) -> None:
raise RuntimeError raise RuntimeError
layout.attach_timer_fn(dummy_set_timer) layout.attach_timer_fn(dummy_set_timer)
ui.backlight_fade(ui.style.BACKLIGHT_DIM) ui.backlight_fade(ui.style.get_backlight_dim())
layout.paint() layout.paint()
ui.refresh() ui.refresh()
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL) ui.backlight_fade(ui.style.get_backlight_normal())
async def raise_if_not_confirmed( async def raise_if_not_confirmed(
@ -1562,3 +1562,11 @@ def confirm_firmware_update(description: str, fingerprint: str) -> Awaitable[Non
BR_TYPE_OTHER, BR_TYPE_OTHER,
) )
) )
async def set_brightness(current: int | None = None) -> None:
await interact(
RustLayout(trezorui2.set_brightness(current=current)),
"set_brightness",
BR_TYPE_OTHER,
)

View File

@ -85,7 +85,6 @@ class Homescreen(HomescreenBase):
class Lockscreen(HomescreenBase): class Lockscreen(HomescreenBase):
RENDER_INDICATOR = storage_cache.LOCKSCREEN_ON RENDER_INDICATOR = storage_cache.LOCKSCREEN_ON
BACKLIGHT_LEVEL = ui.style.BACKLIGHT_LOW
def __init__( def __init__(
self, self,
@ -94,8 +93,9 @@ class Lockscreen(HomescreenBase):
coinjoin_authorized: bool = False, coinjoin_authorized: bool = False,
) -> None: ) -> None:
self.bootscreen = bootscreen self.bootscreen = bootscreen
self.backlight_level = ui.style.get_backlight_low()
if bootscreen: if bootscreen:
self.BACKLIGHT_LEVEL = ui.style.BACKLIGHT_NORMAL self.backlight_level = ui.style.get_backlight_normal()
skip = ( skip = (
not bootscreen and storage_cache.homescreen_shown is self.RENDER_INDICATOR not bootscreen and storage_cache.homescreen_shown is self.RENDER_INDICATOR

View File

@ -1,8 +1,41 @@
from micropython import const from micropython import const
import storage.device
# backlight brightness # backlight brightness
BACKLIGHT_NORMAL = const(150) _BACKLIGHT_NORMAL = const(150)
BACKLIGHT_LOW = const(45) _BACKLIGHT_LOW = const(45)
BACKLIGHT_DIM = const(5) _BACKLIGHT_DIM = const(5)
BACKLIGHT_NONE = const(0) _BACKLIGHT_NONE = const(0)
BACKLIGHT_MAX = const(255) _BACKLIGHT_MIN = const(10)
_BACKLIGHT_MAX = const(255)
def get_backlight_normal() -> int:
val = storage.device.get_brightness()
if val is None:
return _BACKLIGHT_NORMAL
return val
def get_backlight_low() -> int:
val = storage.device.get_brightness()
if val is None or val > _BACKLIGHT_LOW:
return _BACKLIGHT_LOW
return val
def get_backlight_dim() -> int:
return _BACKLIGHT_DIM
def get_backlight_none() -> int:
return _BACKLIGHT_NONE
def get_backlight_min() -> int:
return _BACKLIGHT_MIN
def get_backlight_max() -> int:
return _BACKLIGHT_MAX

View File

@ -81,6 +81,7 @@
"bitcoin__unverified_external_inputs": "The transaction contains unverified external inputs.", "bitcoin__unverified_external_inputs": "The transaction contains unverified external inputs.",
"bitcoin__valid_signature": "The signature is valid.", "bitcoin__valid_signature": "The signature is valid.",
"bitcoin__voting_rights": "Voting rights to:", "bitcoin__voting_rights": "Voting rights to:",
"brightness__title": "Set brightness",
"buttons__abort": "Abort", "buttons__abort": "Abort",
"buttons__access": "Access", "buttons__access": "Access",
"buttons__again": "Again", "buttons__again": "Again",

View File

@ -930,5 +930,6 @@
"928": "words__operation_cancelled", "928": "words__operation_cancelled",
"929": "words__settings", "929": "words__settings",
"930": "words__try_again", "930": "words__try_again",
"931": "reset__slip39_checklist_num_groups_x_template" "931": "reset__slip39_checklist_num_groups_x_template",
"932": "brightness__title"
} }

View File

@ -1,8 +1,8 @@
{ {
"current": { "current": {
"merkle_root": "e406bb0127f82bf476884b46c05ca86993c22e1373c4274443f2aef20b138a8e", "merkle_root": "1e9cb4df51f267f250b45ba4c130f2e46487dc60d8f5e0e19bd398ec4a613f24",
"datetime": "2024-05-28T00:05:41.698473", "datetime": "2024-05-28T09:19:32.720044",
"commit": "342b88f62bcd34595ea81ced550bb579b4e4a813" "commit": "ebb35e8de3ea870b13d85891096136c16bac2cc5"
}, },
"history": [ "history": [
{ {

View File

@ -10,7 +10,8 @@ SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdPro
EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \ EthereumTypedDataValueRequest EthereumTypedDataValueAck ShowDeviceTutorial \
UnlockBootloader AuthenticateDevice AuthenticityProof \ UnlockBootloader AuthenticateDevice AuthenticityProof \
Solana StellarClaimClaimableBalanceOp \ Solana StellarClaimClaimableBalanceOp \
ChangeLanguage TranslationDataRequest TranslationDataAck ChangeLanguage TranslationDataRequest TranslationDataAck \
SetBrightness \
ifeq ($(BITCOIN_ONLY), 1) ifeq ($(BITCOIN_ONLY), 1)
SKIPPED_MESSAGES += Ethereum NEM Stellar SKIPPED_MESSAGES += Ethereum NEM Stellar

View File

@ -0,0 +1 @@
Added user adjustable brightness setting.

View File

@ -206,6 +206,13 @@ def label(client: "TrezorClient", label: str) -> str:
return device.apply_settings(client, label=label) return device.apply_settings(client, label=label)
@cli.command()
@with_client
def brightness(client: "TrezorClient") -> str:
"""Set display brightness."""
return device.set_brightness(client)
@cli.command() @cli.command()
@click.argument("path_or_url", required=False) @click.argument("path_or_url", required=False)
@click.option( @click.option(

View File

@ -348,3 +348,10 @@ def set_busy(client: "TrezorClient", expiry_ms: Optional[int]) -> "MessageType":
@expect(messages.AuthenticityProof) @expect(messages.AuthenticityProof)
def authenticate(client: "TrezorClient", challenge: bytes): def authenticate(client: "TrezorClient", challenge: bytes):
return client.call(messages.AuthenticateDevice(challenge=challenge)) return client.call(messages.AuthenticateDevice(challenge=challenge))
@expect(messages.Success, field="message", ret_type=str)
def set_brightness(
client: "TrezorClient", value: Optional[int] = None
) -> "MessageType":
return client.call(messages.SetBrightness(value=value))

View File

@ -78,6 +78,7 @@ class MessageType(IntEnum):
ChangeLanguage = 990 ChangeLanguage = 990
TranslationDataRequest = 991 TranslationDataRequest = 991
TranslationDataAck = 992 TranslationDataAck = 992
SetBrightness = 993
SetU2FCounter = 63 SetU2FCounter = 63
GetNextU2FCounter = 80 GetNextU2FCounter = 80
NextU2FCounter = 81 NextU2FCounter = 81
@ -491,6 +492,7 @@ class Capability(IntEnum):
PassphraseEntry = 17 PassphraseEntry = 17
Solana = 18 Solana = 18
Translations = 19 Translations = 19
Brightness = 20
class SdProtectOperationType(IntEnum): class SdProtectOperationType(IntEnum):
@ -3950,6 +3952,20 @@ class UnlockBootloader(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 96 MESSAGE_WIRE_TYPE = 96
class SetBrightness(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 993
FIELDS = {
1: protobuf.Field("value", "uint32", repeated=False, required=False, default=None),
}
def __init__(
self,
*,
value: Optional["int"] = None,
) -> None:
self.value = value
class Slip39Group(protobuf.MessageType): class Slip39Group(protobuf.MessageType):
MESSAGE_WIRE_TYPE = None MESSAGE_WIRE_TYPE = None
FIELDS = { FIELDS = {

View File

@ -48,6 +48,7 @@ trezor_message_impl! {
ChangeLanguage => MessageType_ChangeLanguage, ChangeLanguage => MessageType_ChangeLanguage,
TranslationDataRequest => MessageType_TranslationDataRequest, TranslationDataRequest => MessageType_TranslationDataRequest,
TranslationDataAck => MessageType_TranslationDataAck, TranslationDataAck => MessageType_TranslationDataAck,
SetBrightness => MessageType_SetBrightness,
SetU2FCounter => MessageType_SetU2FCounter, SetU2FCounter => MessageType_SetU2FCounter,
GetNextU2FCounter => MessageType_GetNextU2FCounter, GetNextU2FCounter => MessageType_GetNextU2FCounter,
NextU2FCounter => MessageType_NextU2FCounter, NextU2FCounter => MessageType_NextU2FCounter,

View File

@ -126,6 +126,8 @@ pub enum MessageType {
MessageType_TranslationDataRequest = 991, MessageType_TranslationDataRequest = 991,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TranslationDataAck) // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_TranslationDataAck)
MessageType_TranslationDataAck = 992, MessageType_TranslationDataAck = 992,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SetBrightness)
MessageType_SetBrightness = 993,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SetU2FCounter) // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SetU2FCounter)
MessageType_SetU2FCounter = 63, MessageType_SetU2FCounter = 63,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_GetNextU2FCounter) // @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_GetNextU2FCounter)
@ -574,6 +576,7 @@ impl ::protobuf::Enum for MessageType {
990 => ::std::option::Option::Some(MessageType::MessageType_ChangeLanguage), 990 => ::std::option::Option::Some(MessageType::MessageType_ChangeLanguage),
991 => ::std::option::Option::Some(MessageType::MessageType_TranslationDataRequest), 991 => ::std::option::Option::Some(MessageType::MessageType_TranslationDataRequest),
992 => ::std::option::Option::Some(MessageType::MessageType_TranslationDataAck), 992 => ::std::option::Option::Some(MessageType::MessageType_TranslationDataAck),
993 => ::std::option::Option::Some(MessageType::MessageType_SetBrightness),
63 => ::std::option::Option::Some(MessageType::MessageType_SetU2FCounter), 63 => ::std::option::Option::Some(MessageType::MessageType_SetU2FCounter),
80 => ::std::option::Option::Some(MessageType::MessageType_GetNextU2FCounter), 80 => ::std::option::Option::Some(MessageType::MessageType_GetNextU2FCounter),
81 => ::std::option::Option::Some(MessageType::MessageType_NextU2FCounter), 81 => ::std::option::Option::Some(MessageType::MessageType_NextU2FCounter),
@ -823,6 +826,7 @@ impl ::protobuf::Enum for MessageType {
"MessageType_ChangeLanguage" => ::std::option::Option::Some(MessageType::MessageType_ChangeLanguage), "MessageType_ChangeLanguage" => ::std::option::Option::Some(MessageType::MessageType_ChangeLanguage),
"MessageType_TranslationDataRequest" => ::std::option::Option::Some(MessageType::MessageType_TranslationDataRequest), "MessageType_TranslationDataRequest" => ::std::option::Option::Some(MessageType::MessageType_TranslationDataRequest),
"MessageType_TranslationDataAck" => ::std::option::Option::Some(MessageType::MessageType_TranslationDataAck), "MessageType_TranslationDataAck" => ::std::option::Option::Some(MessageType::MessageType_TranslationDataAck),
"MessageType_SetBrightness" => ::std::option::Option::Some(MessageType::MessageType_SetBrightness),
"MessageType_SetU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_SetU2FCounter), "MessageType_SetU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_SetU2FCounter),
"MessageType_GetNextU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_GetNextU2FCounter), "MessageType_GetNextU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_GetNextU2FCounter),
"MessageType_NextU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_NextU2FCounter), "MessageType_NextU2FCounter" => ::std::option::Option::Some(MessageType::MessageType_NextU2FCounter),
@ -1071,6 +1075,7 @@ impl ::protobuf::Enum for MessageType {
MessageType::MessageType_ChangeLanguage, MessageType::MessageType_ChangeLanguage,
MessageType::MessageType_TranslationDataRequest, MessageType::MessageType_TranslationDataRequest,
MessageType::MessageType_TranslationDataAck, MessageType::MessageType_TranslationDataAck,
MessageType::MessageType_SetBrightness,
MessageType::MessageType_SetU2FCounter, MessageType::MessageType_SetU2FCounter,
MessageType::MessageType_GetNextU2FCounter, MessageType::MessageType_GetNextU2FCounter,
MessageType::MessageType_NextU2FCounter, MessageType::MessageType_NextU2FCounter,
@ -1325,200 +1330,201 @@ impl ::protobuf::EnumFull for MessageType {
MessageType::MessageType_ChangeLanguage => 46, MessageType::MessageType_ChangeLanguage => 46,
MessageType::MessageType_TranslationDataRequest => 47, MessageType::MessageType_TranslationDataRequest => 47,
MessageType::MessageType_TranslationDataAck => 48, MessageType::MessageType_TranslationDataAck => 48,
MessageType::MessageType_SetU2FCounter => 49, MessageType::MessageType_SetBrightness => 49,
MessageType::MessageType_GetNextU2FCounter => 50, MessageType::MessageType_SetU2FCounter => 50,
MessageType::MessageType_NextU2FCounter => 51, MessageType::MessageType_GetNextU2FCounter => 51,
MessageType::MessageType_Deprecated_PassphraseStateRequest => 52, MessageType::MessageType_NextU2FCounter => 52,
MessageType::MessageType_Deprecated_PassphraseStateAck => 53, MessageType::MessageType_Deprecated_PassphraseStateRequest => 53,
MessageType::MessageType_FirmwareErase => 54, MessageType::MessageType_Deprecated_PassphraseStateAck => 54,
MessageType::MessageType_FirmwareUpload => 55, MessageType::MessageType_FirmwareErase => 55,
MessageType::MessageType_FirmwareRequest => 56, MessageType::MessageType_FirmwareUpload => 56,
MessageType::MessageType_ProdTestT1 => 57, MessageType::MessageType_FirmwareRequest => 57,
MessageType::MessageType_GetPublicKey => 58, MessageType::MessageType_ProdTestT1 => 58,
MessageType::MessageType_PublicKey => 59, MessageType::MessageType_GetPublicKey => 59,
MessageType::MessageType_SignTx => 60, MessageType::MessageType_PublicKey => 60,
MessageType::MessageType_TxRequest => 61, MessageType::MessageType_SignTx => 61,
MessageType::MessageType_TxAck => 62, MessageType::MessageType_TxRequest => 62,
MessageType::MessageType_GetAddress => 63, MessageType::MessageType_TxAck => 63,
MessageType::MessageType_Address => 64, MessageType::MessageType_GetAddress => 64,
MessageType::MessageType_TxAckPaymentRequest => 65, MessageType::MessageType_Address => 65,
MessageType::MessageType_SignMessage => 66, MessageType::MessageType_TxAckPaymentRequest => 66,
MessageType::MessageType_VerifyMessage => 67, MessageType::MessageType_SignMessage => 67,
MessageType::MessageType_MessageSignature => 68, MessageType::MessageType_VerifyMessage => 68,
MessageType::MessageType_GetOwnershipId => 69, MessageType::MessageType_MessageSignature => 69,
MessageType::MessageType_OwnershipId => 70, MessageType::MessageType_GetOwnershipId => 70,
MessageType::MessageType_GetOwnershipProof => 71, MessageType::MessageType_OwnershipId => 71,
MessageType::MessageType_OwnershipProof => 72, MessageType::MessageType_GetOwnershipProof => 72,
MessageType::MessageType_AuthorizeCoinJoin => 73, MessageType::MessageType_OwnershipProof => 73,
MessageType::MessageType_CipherKeyValue => 74, MessageType::MessageType_AuthorizeCoinJoin => 74,
MessageType::MessageType_CipheredKeyValue => 75, MessageType::MessageType_CipherKeyValue => 75,
MessageType::MessageType_SignIdentity => 76, MessageType::MessageType_CipheredKeyValue => 76,
MessageType::MessageType_SignedIdentity => 77, MessageType::MessageType_SignIdentity => 77,
MessageType::MessageType_GetECDHSessionKey => 78, MessageType::MessageType_SignedIdentity => 78,
MessageType::MessageType_ECDHSessionKey => 79, MessageType::MessageType_GetECDHSessionKey => 79,
MessageType::MessageType_CosiCommit => 80, MessageType::MessageType_ECDHSessionKey => 80,
MessageType::MessageType_CosiCommitment => 81, MessageType::MessageType_CosiCommit => 81,
MessageType::MessageType_CosiSign => 82, MessageType::MessageType_CosiCommitment => 82,
MessageType::MessageType_CosiSignature => 83, MessageType::MessageType_CosiSign => 83,
MessageType::MessageType_DebugLinkDecision => 84, MessageType::MessageType_CosiSignature => 84,
MessageType::MessageType_DebugLinkGetState => 85, MessageType::MessageType_DebugLinkDecision => 85,
MessageType::MessageType_DebugLinkState => 86, MessageType::MessageType_DebugLinkGetState => 86,
MessageType::MessageType_DebugLinkStop => 87, MessageType::MessageType_DebugLinkState => 87,
MessageType::MessageType_DebugLinkLog => 88, MessageType::MessageType_DebugLinkStop => 88,
MessageType::MessageType_DebugLinkMemoryRead => 89, MessageType::MessageType_DebugLinkLog => 89,
MessageType::MessageType_DebugLinkMemory => 90, MessageType::MessageType_DebugLinkMemoryRead => 90,
MessageType::MessageType_DebugLinkMemoryWrite => 91, MessageType::MessageType_DebugLinkMemory => 91,
MessageType::MessageType_DebugLinkFlashErase => 92, MessageType::MessageType_DebugLinkMemoryWrite => 92,
MessageType::MessageType_DebugLinkLayout => 93, MessageType::MessageType_DebugLinkFlashErase => 93,
MessageType::MessageType_DebugLinkReseedRandom => 94, MessageType::MessageType_DebugLinkLayout => 94,
MessageType::MessageType_DebugLinkRecordScreen => 95, MessageType::MessageType_DebugLinkReseedRandom => 95,
MessageType::MessageType_DebugLinkEraseSdCard => 96, MessageType::MessageType_DebugLinkRecordScreen => 96,
MessageType::MessageType_DebugLinkWatchLayout => 97, MessageType::MessageType_DebugLinkEraseSdCard => 97,
MessageType::MessageType_DebugLinkResetDebugEvents => 98, MessageType::MessageType_DebugLinkWatchLayout => 98,
MessageType::MessageType_EthereumGetPublicKey => 99, MessageType::MessageType_DebugLinkResetDebugEvents => 99,
MessageType::MessageType_EthereumPublicKey => 100, MessageType::MessageType_EthereumGetPublicKey => 100,
MessageType::MessageType_EthereumGetAddress => 101, MessageType::MessageType_EthereumPublicKey => 101,
MessageType::MessageType_EthereumAddress => 102, MessageType::MessageType_EthereumGetAddress => 102,
MessageType::MessageType_EthereumSignTx => 103, MessageType::MessageType_EthereumAddress => 103,
MessageType::MessageType_EthereumSignTxEIP1559 => 104, MessageType::MessageType_EthereumSignTx => 104,
MessageType::MessageType_EthereumTxRequest => 105, MessageType::MessageType_EthereumSignTxEIP1559 => 105,
MessageType::MessageType_EthereumTxAck => 106, MessageType::MessageType_EthereumTxRequest => 106,
MessageType::MessageType_EthereumSignMessage => 107, MessageType::MessageType_EthereumTxAck => 107,
MessageType::MessageType_EthereumVerifyMessage => 108, MessageType::MessageType_EthereumSignMessage => 108,
MessageType::MessageType_EthereumMessageSignature => 109, MessageType::MessageType_EthereumVerifyMessage => 109,
MessageType::MessageType_EthereumSignTypedData => 110, MessageType::MessageType_EthereumMessageSignature => 110,
MessageType::MessageType_EthereumTypedDataStructRequest => 111, MessageType::MessageType_EthereumSignTypedData => 111,
MessageType::MessageType_EthereumTypedDataStructAck => 112, MessageType::MessageType_EthereumTypedDataStructRequest => 112,
MessageType::MessageType_EthereumTypedDataValueRequest => 113, MessageType::MessageType_EthereumTypedDataStructAck => 113,
MessageType::MessageType_EthereumTypedDataValueAck => 114, MessageType::MessageType_EthereumTypedDataValueRequest => 114,
MessageType::MessageType_EthereumTypedDataSignature => 115, MessageType::MessageType_EthereumTypedDataValueAck => 115,
MessageType::MessageType_EthereumSignTypedHash => 116, MessageType::MessageType_EthereumTypedDataSignature => 116,
MessageType::MessageType_NEMGetAddress => 117, MessageType::MessageType_EthereumSignTypedHash => 117,
MessageType::MessageType_NEMAddress => 118, MessageType::MessageType_NEMGetAddress => 118,
MessageType::MessageType_NEMSignTx => 119, MessageType::MessageType_NEMAddress => 119,
MessageType::MessageType_NEMSignedTx => 120, MessageType::MessageType_NEMSignTx => 120,
MessageType::MessageType_NEMDecryptMessage => 121, MessageType::MessageType_NEMSignedTx => 121,
MessageType::MessageType_NEMDecryptedMessage => 122, MessageType::MessageType_NEMDecryptMessage => 122,
MessageType::MessageType_TezosGetAddress => 123, MessageType::MessageType_NEMDecryptedMessage => 123,
MessageType::MessageType_TezosAddress => 124, MessageType::MessageType_TezosGetAddress => 124,
MessageType::MessageType_TezosSignTx => 125, MessageType::MessageType_TezosAddress => 125,
MessageType::MessageType_TezosSignedTx => 126, MessageType::MessageType_TezosSignTx => 126,
MessageType::MessageType_TezosGetPublicKey => 127, MessageType::MessageType_TezosSignedTx => 127,
MessageType::MessageType_TezosPublicKey => 128, MessageType::MessageType_TezosGetPublicKey => 128,
MessageType::MessageType_StellarSignTx => 129, MessageType::MessageType_TezosPublicKey => 129,
MessageType::MessageType_StellarTxOpRequest => 130, MessageType::MessageType_StellarSignTx => 130,
MessageType::MessageType_StellarGetAddress => 131, MessageType::MessageType_StellarTxOpRequest => 131,
MessageType::MessageType_StellarAddress => 132, MessageType::MessageType_StellarGetAddress => 132,
MessageType::MessageType_StellarCreateAccountOp => 133, MessageType::MessageType_StellarAddress => 133,
MessageType::MessageType_StellarPaymentOp => 134, MessageType::MessageType_StellarCreateAccountOp => 134,
MessageType::MessageType_StellarPathPaymentStrictReceiveOp => 135, MessageType::MessageType_StellarPaymentOp => 135,
MessageType::MessageType_StellarManageSellOfferOp => 136, MessageType::MessageType_StellarPathPaymentStrictReceiveOp => 136,
MessageType::MessageType_StellarCreatePassiveSellOfferOp => 137, MessageType::MessageType_StellarManageSellOfferOp => 137,
MessageType::MessageType_StellarSetOptionsOp => 138, MessageType::MessageType_StellarCreatePassiveSellOfferOp => 138,
MessageType::MessageType_StellarChangeTrustOp => 139, MessageType::MessageType_StellarSetOptionsOp => 139,
MessageType::MessageType_StellarAllowTrustOp => 140, MessageType::MessageType_StellarChangeTrustOp => 140,
MessageType::MessageType_StellarAccountMergeOp => 141, MessageType::MessageType_StellarAllowTrustOp => 141,
MessageType::MessageType_StellarManageDataOp => 142, MessageType::MessageType_StellarAccountMergeOp => 142,
MessageType::MessageType_StellarBumpSequenceOp => 143, MessageType::MessageType_StellarManageDataOp => 143,
MessageType::MessageType_StellarManageBuyOfferOp => 144, MessageType::MessageType_StellarBumpSequenceOp => 144,
MessageType::MessageType_StellarPathPaymentStrictSendOp => 145, MessageType::MessageType_StellarManageBuyOfferOp => 145,
MessageType::MessageType_StellarClaimClaimableBalanceOp => 146, MessageType::MessageType_StellarPathPaymentStrictSendOp => 146,
MessageType::MessageType_StellarSignedTx => 147, MessageType::MessageType_StellarClaimClaimableBalanceOp => 147,
MessageType::MessageType_CardanoGetPublicKey => 148, MessageType::MessageType_StellarSignedTx => 148,
MessageType::MessageType_CardanoPublicKey => 149, MessageType::MessageType_CardanoGetPublicKey => 149,
MessageType::MessageType_CardanoGetAddress => 150, MessageType::MessageType_CardanoPublicKey => 150,
MessageType::MessageType_CardanoAddress => 151, MessageType::MessageType_CardanoGetAddress => 151,
MessageType::MessageType_CardanoTxItemAck => 152, MessageType::MessageType_CardanoAddress => 152,
MessageType::MessageType_CardanoTxAuxiliaryDataSupplement => 153, MessageType::MessageType_CardanoTxItemAck => 153,
MessageType::MessageType_CardanoTxWitnessRequest => 154, MessageType::MessageType_CardanoTxAuxiliaryDataSupplement => 154,
MessageType::MessageType_CardanoTxWitnessResponse => 155, MessageType::MessageType_CardanoTxWitnessRequest => 155,
MessageType::MessageType_CardanoTxHostAck => 156, MessageType::MessageType_CardanoTxWitnessResponse => 156,
MessageType::MessageType_CardanoTxBodyHash => 157, MessageType::MessageType_CardanoTxHostAck => 157,
MessageType::MessageType_CardanoSignTxFinished => 158, MessageType::MessageType_CardanoTxBodyHash => 158,
MessageType::MessageType_CardanoSignTxInit => 159, MessageType::MessageType_CardanoSignTxFinished => 159,
MessageType::MessageType_CardanoTxInput => 160, MessageType::MessageType_CardanoSignTxInit => 160,
MessageType::MessageType_CardanoTxOutput => 161, MessageType::MessageType_CardanoTxInput => 161,
MessageType::MessageType_CardanoAssetGroup => 162, MessageType::MessageType_CardanoTxOutput => 162,
MessageType::MessageType_CardanoToken => 163, MessageType::MessageType_CardanoAssetGroup => 163,
MessageType::MessageType_CardanoTxCertificate => 164, MessageType::MessageType_CardanoToken => 164,
MessageType::MessageType_CardanoTxWithdrawal => 165, MessageType::MessageType_CardanoTxCertificate => 165,
MessageType::MessageType_CardanoTxAuxiliaryData => 166, MessageType::MessageType_CardanoTxWithdrawal => 166,
MessageType::MessageType_CardanoPoolOwner => 167, MessageType::MessageType_CardanoTxAuxiliaryData => 167,
MessageType::MessageType_CardanoPoolRelayParameters => 168, MessageType::MessageType_CardanoPoolOwner => 168,
MessageType::MessageType_CardanoGetNativeScriptHash => 169, MessageType::MessageType_CardanoPoolRelayParameters => 169,
MessageType::MessageType_CardanoNativeScriptHash => 170, MessageType::MessageType_CardanoGetNativeScriptHash => 170,
MessageType::MessageType_CardanoTxMint => 171, MessageType::MessageType_CardanoNativeScriptHash => 171,
MessageType::MessageType_CardanoTxCollateralInput => 172, MessageType::MessageType_CardanoTxMint => 172,
MessageType::MessageType_CardanoTxRequiredSigner => 173, MessageType::MessageType_CardanoTxCollateralInput => 173,
MessageType::MessageType_CardanoTxInlineDatumChunk => 174, MessageType::MessageType_CardanoTxRequiredSigner => 174,
MessageType::MessageType_CardanoTxReferenceScriptChunk => 175, MessageType::MessageType_CardanoTxInlineDatumChunk => 175,
MessageType::MessageType_CardanoTxReferenceInput => 176, MessageType::MessageType_CardanoTxReferenceScriptChunk => 176,
MessageType::MessageType_RippleGetAddress => 177, MessageType::MessageType_CardanoTxReferenceInput => 177,
MessageType::MessageType_RippleAddress => 178, MessageType::MessageType_RippleGetAddress => 178,
MessageType::MessageType_RippleSignTx => 179, MessageType::MessageType_RippleAddress => 179,
MessageType::MessageType_RippleSignedTx => 180, MessageType::MessageType_RippleSignTx => 180,
MessageType::MessageType_MoneroTransactionInitRequest => 181, MessageType::MessageType_RippleSignedTx => 181,
MessageType::MessageType_MoneroTransactionInitAck => 182, MessageType::MessageType_MoneroTransactionInitRequest => 182,
MessageType::MessageType_MoneroTransactionSetInputRequest => 183, MessageType::MessageType_MoneroTransactionInitAck => 183,
MessageType::MessageType_MoneroTransactionSetInputAck => 184, MessageType::MessageType_MoneroTransactionSetInputRequest => 184,
MessageType::MessageType_MoneroTransactionInputViniRequest => 185, MessageType::MessageType_MoneroTransactionSetInputAck => 185,
MessageType::MessageType_MoneroTransactionInputViniAck => 186, MessageType::MessageType_MoneroTransactionInputViniRequest => 186,
MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 187, MessageType::MessageType_MoneroTransactionInputViniAck => 187,
MessageType::MessageType_MoneroTransactionAllInputsSetAck => 188, MessageType::MessageType_MoneroTransactionAllInputsSetRequest => 188,
MessageType::MessageType_MoneroTransactionSetOutputRequest => 189, MessageType::MessageType_MoneroTransactionAllInputsSetAck => 189,
MessageType::MessageType_MoneroTransactionSetOutputAck => 190, MessageType::MessageType_MoneroTransactionSetOutputRequest => 190,
MessageType::MessageType_MoneroTransactionAllOutSetRequest => 191, MessageType::MessageType_MoneroTransactionSetOutputAck => 191,
MessageType::MessageType_MoneroTransactionAllOutSetAck => 192, MessageType::MessageType_MoneroTransactionAllOutSetRequest => 192,
MessageType::MessageType_MoneroTransactionSignInputRequest => 193, MessageType::MessageType_MoneroTransactionAllOutSetAck => 193,
MessageType::MessageType_MoneroTransactionSignInputAck => 194, MessageType::MessageType_MoneroTransactionSignInputRequest => 194,
MessageType::MessageType_MoneroTransactionFinalRequest => 195, MessageType::MessageType_MoneroTransactionSignInputAck => 195,
MessageType::MessageType_MoneroTransactionFinalAck => 196, MessageType::MessageType_MoneroTransactionFinalRequest => 196,
MessageType::MessageType_MoneroKeyImageExportInitRequest => 197, MessageType::MessageType_MoneroTransactionFinalAck => 197,
MessageType::MessageType_MoneroKeyImageExportInitAck => 198, MessageType::MessageType_MoneroKeyImageExportInitRequest => 198,
MessageType::MessageType_MoneroKeyImageSyncStepRequest => 199, MessageType::MessageType_MoneroKeyImageExportInitAck => 199,
MessageType::MessageType_MoneroKeyImageSyncStepAck => 200, MessageType::MessageType_MoneroKeyImageSyncStepRequest => 200,
MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 201, MessageType::MessageType_MoneroKeyImageSyncStepAck => 201,
MessageType::MessageType_MoneroKeyImageSyncFinalAck => 202, MessageType::MessageType_MoneroKeyImageSyncFinalRequest => 202,
MessageType::MessageType_MoneroGetAddress => 203, MessageType::MessageType_MoneroKeyImageSyncFinalAck => 203,
MessageType::MessageType_MoneroAddress => 204, MessageType::MessageType_MoneroGetAddress => 204,
MessageType::MessageType_MoneroGetWatchKey => 205, MessageType::MessageType_MoneroAddress => 205,
MessageType::MessageType_MoneroWatchKey => 206, MessageType::MessageType_MoneroGetWatchKey => 206,
MessageType::MessageType_DebugMoneroDiagRequest => 207, MessageType::MessageType_MoneroWatchKey => 207,
MessageType::MessageType_DebugMoneroDiagAck => 208, MessageType::MessageType_DebugMoneroDiagRequest => 208,
MessageType::MessageType_MoneroGetTxKeyRequest => 209, MessageType::MessageType_DebugMoneroDiagAck => 209,
MessageType::MessageType_MoneroGetTxKeyAck => 210, MessageType::MessageType_MoneroGetTxKeyRequest => 210,
MessageType::MessageType_MoneroLiveRefreshStartRequest => 211, MessageType::MessageType_MoneroGetTxKeyAck => 211,
MessageType::MessageType_MoneroLiveRefreshStartAck => 212, MessageType::MessageType_MoneroLiveRefreshStartRequest => 212,
MessageType::MessageType_MoneroLiveRefreshStepRequest => 213, MessageType::MessageType_MoneroLiveRefreshStartAck => 213,
MessageType::MessageType_MoneroLiveRefreshStepAck => 214, MessageType::MessageType_MoneroLiveRefreshStepRequest => 214,
MessageType::MessageType_MoneroLiveRefreshFinalRequest => 215, MessageType::MessageType_MoneroLiveRefreshStepAck => 215,
MessageType::MessageType_MoneroLiveRefreshFinalAck => 216, MessageType::MessageType_MoneroLiveRefreshFinalRequest => 216,
MessageType::MessageType_EosGetPublicKey => 217, MessageType::MessageType_MoneroLiveRefreshFinalAck => 217,
MessageType::MessageType_EosPublicKey => 218, MessageType::MessageType_EosGetPublicKey => 218,
MessageType::MessageType_EosSignTx => 219, MessageType::MessageType_EosPublicKey => 219,
MessageType::MessageType_EosTxActionRequest => 220, MessageType::MessageType_EosSignTx => 220,
MessageType::MessageType_EosTxActionAck => 221, MessageType::MessageType_EosTxActionRequest => 221,
MessageType::MessageType_EosSignedTx => 222, MessageType::MessageType_EosTxActionAck => 222,
MessageType::MessageType_BinanceGetAddress => 223, MessageType::MessageType_EosSignedTx => 223,
MessageType::MessageType_BinanceAddress => 224, MessageType::MessageType_BinanceGetAddress => 224,
MessageType::MessageType_BinanceGetPublicKey => 225, MessageType::MessageType_BinanceAddress => 225,
MessageType::MessageType_BinancePublicKey => 226, MessageType::MessageType_BinanceGetPublicKey => 226,
MessageType::MessageType_BinanceSignTx => 227, MessageType::MessageType_BinancePublicKey => 227,
MessageType::MessageType_BinanceTxRequest => 228, MessageType::MessageType_BinanceSignTx => 228,
MessageType::MessageType_BinanceTransferMsg => 229, MessageType::MessageType_BinanceTxRequest => 229,
MessageType::MessageType_BinanceOrderMsg => 230, MessageType::MessageType_BinanceTransferMsg => 230,
MessageType::MessageType_BinanceCancelMsg => 231, MessageType::MessageType_BinanceOrderMsg => 231,
MessageType::MessageType_BinanceSignedTx => 232, MessageType::MessageType_BinanceCancelMsg => 232,
MessageType::MessageType_WebAuthnListResidentCredentials => 233, MessageType::MessageType_BinanceSignedTx => 233,
MessageType::MessageType_WebAuthnCredentials => 234, MessageType::MessageType_WebAuthnListResidentCredentials => 234,
MessageType::MessageType_WebAuthnAddResidentCredential => 235, MessageType::MessageType_WebAuthnCredentials => 235,
MessageType::MessageType_WebAuthnRemoveResidentCredential => 236, MessageType::MessageType_WebAuthnAddResidentCredential => 236,
MessageType::MessageType_SolanaGetPublicKey => 237, MessageType::MessageType_WebAuthnRemoveResidentCredential => 237,
MessageType::MessageType_SolanaPublicKey => 238, MessageType::MessageType_SolanaGetPublicKey => 238,
MessageType::MessageType_SolanaGetAddress => 239, MessageType::MessageType_SolanaPublicKey => 239,
MessageType::MessageType_SolanaAddress => 240, MessageType::MessageType_SolanaGetAddress => 240,
MessageType::MessageType_SolanaSignTx => 241, MessageType::MessageType_SolanaAddress => 241,
MessageType::MessageType_SolanaTxSignature => 242, MessageType::MessageType_SolanaSignTx => 242,
MessageType::MessageType_SolanaTxSignature => 243,
}; };
Self::enum_descriptor().value_by_index(index) Self::enum_descriptor().value_by_index(index)
} }
@ -1568,7 +1574,7 @@ pub mod exts {
static file_descriptor_proto_data: &'static [u8] = b"\ static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\ \n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\
scriptor.proto*\x9aT\n\x0bMessageType\x12(\n\x16MessageType_Initialize\ scriptor.proto*\xc4T\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
\x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\ \x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\
\x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\ \x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\
%\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\ %\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\
@ -1627,86 +1633,87 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x121\n\"MessageType_TranslationData\ \x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x121\n\"MessageType_TranslationData\
Request\x10\xdf\x07\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12-\n\x1eMe\ Request\x10\xdf\x07\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12-\n\x1eMe\
ssageType_TranslationDataAck\x10\xe0\x07\x1a\x08\x80\xa6\x1d\x01\x90\xb5\ ssageType_TranslationDataAck\x10\xe0\x07\x1a\x08\x80\xa6\x1d\x01\x90\xb5\
\x18\x01\x12#\n\x19MessageType_SetU2FCounter\x10?\x1a\x04\x90\xb5\x18\ \x18\x01\x12(\n\x19MessageType_SetBrightness\x10\xe1\x07\x1a\x08\x80\xa6\
\x01\x12'\n\x1dMessageType_GetNextU2FCounter\x10P\x1a\x04\x90\xb5\x18\ \x1d\x01\x90\xb5\x18\x01\x12#\n\x19MessageType_SetU2FCounter\x10?\x1a\
\x01\x12$\n\x1aMessageType_NextU2FCounter\x10Q\x1a\x04\x98\xb5\x18\x01\ \x04\x90\xb5\x18\x01\x12'\n\x1dMessageType_GetNextU2FCounter\x10P\x1a\
\x125\n-MessageType_Deprecated_PassphraseStateRequest\x10M\x1a\x02\x08\ \x04\x90\xb5\x18\x01\x12$\n\x1aMessageType_NextU2FCounter\x10Q\x1a\x04\
\x01\x121\n)MessageType_Deprecated_PassphraseStateAck\x10N\x1a\x02\x08\ \x98\xb5\x18\x01\x125\n-MessageType_Deprecated_PassphraseStateRequest\
\x01\x12+\n\x19MessageType_FirmwareErase\x10\x06\x1a\x0c\xb8\xb5\x18\x01\ \x10M\x1a\x02\x08\x01\x121\n)MessageType_Deprecated_PassphraseStateAck\
\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12,\n\x1aMessageType_FirmwareUpload\ \x10N\x1a\x02\x08\x01\x12+\n\x19MessageType_FirmwareErase\x10\x06\x1a\
\x10\x07\x1a\x0c\xb8\xb5\x18\x01\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12-\n\ \x0c\xb8\xb5\x18\x01\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12,\n\x1aMessageTy\
\x1bMessageType_FirmwareRequest\x10\x08\x1a\x0c\xb8\xb5\x18\x01\x80\xa6\ pe_FirmwareUpload\x10\x07\x1a\x0c\xb8\xb5\x18\x01\x80\xa6\x1d\x01\x90\
\x1d\x01\x98\xb5\x18\x01\x12(\n\x16MessageType_ProdTestT1\x10\x20\x1a\ \xb5\x18\x01\x12-\n\x1bMessageType_FirmwareRequest\x10\x08\x1a\x0c\xb8\
\x0c\xb8\xb5\x18\x01\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12&\n\x18MessageTy\ \xb5\x18\x01\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12(\n\x16MessageType_ProdT\
pe_GetPublicKey\x10\x0b\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12#\n\ estT1\x10\x20\x1a\x0c\xb8\xb5\x18\x01\x80\xa6\x1d\x01\x90\xb5\x18\x01\
\x15MessageType_PublicKey\x10\x0c\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\ \x12&\n\x18MessageType_GetPublicKey\x10\x0b\x1a\x08\x80\xa6\x1d\x01\x90\
\x01\x12\x20\n\x12MessageType_SignTx\x10\x0f\x1a\x08\x80\xa6\x1d\x01\x90\ \xb5\x18\x01\x12#\n\x15MessageType_PublicKey\x10\x0c\x1a\x08\x80\xa6\x1d\
\xb5\x18\x01\x12#\n\x15MessageType_TxRequest\x10\x15\x1a\x08\x80\xa6\x1d\ \x01\x98\xb5\x18\x01\x12\x20\n\x12MessageType_SignTx\x10\x0f\x1a\x08\x80\
\x01\x98\xb5\x18\x01\x12\x1f\n\x11MessageType_TxAck\x10\x16\x1a\x08\x80\ \xa6\x1d\x01\x90\xb5\x18\x01\x12#\n\x15MessageType_TxRequest\x10\x15\x1a\
\xa6\x1d\x01\x90\xb5\x18\x01\x12$\n\x16MessageType_GetAddress\x10\x1d\ \x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12\x1f\n\x11MessageType_TxAck\x10\
\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12!\n\x13MessageType_Address\ \x16\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12$\n\x16MessageType_GetAd\
\x10\x1e\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12)\n\x1fMessageType_T\ dress\x10\x1d\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12!\n\x13MessageT\
xAckPaymentRequest\x10%\x1a\x04\x90\xb5\x18\x01\x12%\n\x17MessageType_Si\ ype_Address\x10\x1e\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12)\n\x1fMe\
gnMessage\x10&\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12'\n\x19Message\ ssageType_TxAckPaymentRequest\x10%\x1a\x04\x90\xb5\x18\x01\x12%\n\x17Mes\
Type_VerifyMessage\x10'\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12*\n\ sageType_SignMessage\x10&\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12'\n\
\x1cMessageType_MessageSignature\x10(\x1a\x08\x80\xa6\x1d\x01\x98\xb5\ \x19MessageType_VerifyMessage\x10'\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\
\x18\x01\x12(\n\x1aMessageType_GetOwnershipId\x10+\x1a\x08\x80\xa6\x1d\ \x01\x12*\n\x1cMessageType_MessageSignature\x10(\x1a\x08\x80\xa6\x1d\x01\
\x01\x90\xb5\x18\x01\x12%\n\x17MessageType_OwnershipId\x10,\x1a\x08\x80\ \x98\xb5\x18\x01\x12(\n\x1aMessageType_GetOwnershipId\x10+\x1a\x08\x80\
\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMessageType_GetOwnershipProof\x10\ \xa6\x1d\x01\x90\xb5\x18\x01\x12%\n\x17MessageType_OwnershipId\x10,\x1a\
1\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMessageType_Ownershi\ \x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMessageType_GetOwnershipP\
pProof\x102\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMessageTyp\ roof\x101\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMessageType_\
e_AuthorizeCoinJoin\x103\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\ OwnershipProof\x102\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMe\
\x1aMessageType_CipherKeyValue\x10\x17\x1a\x08\x80\xa6\x1d\x01\x90\xb5\ ssageType_AuthorizeCoinJoin\x103\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\
\x18\x01\x12*\n\x1cMessageType_CipheredKeyValue\x100\x1a\x08\x80\xa6\x1d\ \x12(\n\x1aMessageType_CipherKeyValue\x10\x17\x1a\x08\x80\xa6\x1d\x01\
\x01\x98\xb5\x18\x01\x12&\n\x18MessageType_SignIdentity\x105\x1a\x08\x80\ \x90\xb5\x18\x01\x12*\n\x1cMessageType_CipheredKeyValue\x100\x1a\x08\x80\
\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMessageType_SignedIdentity\x106\ \xa6\x1d\x01\x98\xb5\x18\x01\x12&\n\x18MessageType_SignIdentity\x105\x1a\
\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMessageType_GetECDHSe\ \x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMessageType_SignedIdentit\
ssionKey\x10=\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMessageT\ y\x106\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12+\n\x1dMessageType_Get\
ype_ECDHSessionKey\x10>\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x12$\n\ ECDHSessionKey\x10=\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12(\n\x1aMe\
\x16MessageType_CosiCommit\x10G\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\ ssageType_ECDHSessionKey\x10>\x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\
\x12(\n\x1aMessageType_CosiCommitment\x10H\x1a\x08\x80\xa6\x1d\x01\x98\ \x12$\n\x16MessageType_CosiCommit\x10G\x1a\x08\x80\xa6\x1d\x01\x90\xb5\
\xb5\x18\x01\x12\"\n\x14MessageType_CosiSign\x10I\x1a\x08\x80\xa6\x1d\ \x18\x01\x12(\n\x1aMessageType_CosiCommitment\x10H\x1a\x08\x80\xa6\x1d\
\x01\x90\xb5\x18\x01\x12'\n\x19MessageType_CosiSignature\x10J\x1a\x08\ \x01\x98\xb5\x18\x01\x12\"\n\x14MessageType_CosiSign\x10I\x1a\x08\x80\
\x80\xa6\x1d\x01\x98\xb5\x18\x01\x123\n\x1dMessageType_DebugLinkDecision\ \xa6\x1d\x01\x90\xb5\x18\x01\x12'\n\x19MessageType_CosiSignature\x10J\
\x10d\x1a\x10\xc0\xb5\x18\x01\xb0\xb5\x18\x01\x80\xa6\x1d\x01\xa0\xb5\ \x1a\x08\x80\xa6\x1d\x01\x98\xb5\x18\x01\x123\n\x1dMessageType_DebugLink\
\x18\x01\x12/\n\x1dMessageType_DebugLinkGetState\x10e\x1a\x0c\x80\xa6\ Decision\x10d\x1a\x10\xc0\xb5\x18\x01\xb0\xb5\x18\x01\x80\xa6\x1d\x01\
\x1d\x01\xb0\xb5\x18\x01\xa0\xb5\x18\x01\x12(\n\x1aMessageType_DebugLink\ \xa0\xb5\x18\x01\x12/\n\x1dMessageType_DebugLinkGetState\x10e\x1a\x0c\
State\x10f\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12'\n\x19MessageType\ \x80\xa6\x1d\x01\xb0\xb5\x18\x01\xa0\xb5\x18\x01\x12(\n\x1aMessageType_D\
_DebugLinkStop\x10g\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12&\n\x18Me\ ebugLinkState\x10f\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12'\n\x19Mes\
ssageType_DebugLinkLog\x10h\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12-\ sageType_DebugLinkStop\x10g\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12&\
\n\x1fMessageType_DebugLinkMemoryRead\x10n\x1a\x08\x80\xa6\x1d\x01\xa0\ \n\x18MessageType_DebugLinkLog\x10h\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\
\xb5\x18\x01\x12)\n\x1bMessageType_DebugLinkMemory\x10o\x1a\x08\x80\xa6\ \x01\x12-\n\x1fMessageType_DebugLinkMemoryRead\x10n\x1a\x08\x80\xa6\x1d\
\x1d\x01\xa8\xb5\x18\x01\x12.\n\x20MessageType_DebugLinkMemoryWrite\x10p\ \x01\xa0\xb5\x18\x01\x12)\n\x1bMessageType_DebugLinkMemory\x10o\x1a\x08\
\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12-\n\x1fMessageType_DebugLink\ \x80\xa6\x1d\x01\xa8\xb5\x18\x01\x12.\n\x20MessageType_DebugLinkMemoryWr\
FlashErase\x10q\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12*\n\x1bMessag\ ite\x10p\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12-\n\x1fMessageType_D\
eType_DebugLinkLayout\x10\xa9F\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\x18\x01\ ebugLinkFlashErase\x10q\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12*\n\
\x120\n!MessageType_DebugLinkReseedRandom\x10\xaaF\x1a\x08\x80\xa6\x1d\ \x1bMessageType_DebugLinkLayout\x10\xa9F\x1a\x08\x80\xa6\x1d\x01\xa8\xb5\
\x01\xa0\xb5\x18\x01\x120\n!MessageType_DebugLinkRecordScreen\x10\xabF\ \x18\x01\x120\n!MessageType_DebugLinkReseedRandom\x10\xaaF\x1a\x08\x80\
\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20MessageType_DebugLink\ \xa6\x1d\x01\xa0\xb5\x18\x01\x120\n!MessageType_DebugLinkRecordScreen\
EraseSdCard\x10\xadF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20M\ \x10\xabF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12/\n\x20MessageType_\
essageType_DebugLinkWatchLayout\x10\xaeF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\ DebugLinkEraseSdCard\x10\xadF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\
\x18\x01\x124\n%MessageType_DebugLinkResetDebugEvents\x10\xafF\x1a\x08\ \x12/\n\x20MessageType_DebugLinkWatchLayout\x10\xaeF\x1a\x08\x80\xa6\x1d\
\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12+\n\x20MessageType_EthereumGetPublic\ \x01\xa0\xb5\x18\x01\x124\n%MessageType_DebugLinkResetDebugEvents\x10\
Key\x10\xc2\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageType_EthereumPu\ \xafF\x1a\x08\x80\xa6\x1d\x01\xa0\xb5\x18\x01\x12+\n\x20MessageType_Ethe\
blicKey\x10\xc3\x03\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessageType_Ethere\ reumGetPublicKey\x10\xc2\x03\x1a\x04\x90\xb5\x18\x01\x12(\n\x1dMessageTy\
umGetAddress\x108\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessageType_Ethereum\ pe_EthereumPublicKey\x10\xc3\x03\x1a\x04\x98\xb5\x18\x01\x12(\n\x1eMessa\
Address\x109\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_EthereumSignT\ geType_EthereumGetAddress\x108\x1a\x04\x90\xb5\x18\x01\x12%\n\x1bMessage\
x\x10:\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_EthereumSignTxEIP1559\ Type_EthereumAddress\x109\x1a\x04\x98\xb5\x18\x01\x12$\n\x1aMessageType_\
\x10\xc4\x03\x1a\x04\x90\xb5\x18\x01\x12'\n\x1dMessageType_EthereumTxReq\ EthereumSignTx\x10:\x1a\x04\x90\xb5\x18\x01\x12,\n!MessageType_EthereumS\
uest\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_EthereumTxAck\ ignTxEIP1559\x10\xc4\x03\x1a\x04\x90\xb5\x18\x01\x12'\n\x1dMessageType_E\
\x10<\x1a\x04\x90\xb5\x18\x01\x12)\n\x1fMessageType_EthereumSignMessage\ thereumTxRequest\x10;\x1a\x04\x98\xb5\x18\x01\x12#\n\x19MessageType_Ethe\
\x10@\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumVerifyMessage\ reumTxAck\x10<\x1a\x04\x90\xb5\x18\x01\x12)\n\x1fMessageType_EthereumSig\
\x10A\x1a\x04\x90\xb5\x18\x01\x12.\n$MessageType_EthereumMessageSignatur\ nMessage\x10@\x1a\x04\x90\xb5\x18\x01\x12+\n!MessageType_EthereumVerifyM\
e\x10B\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_EthereumSignTypedData\ essage\x10A\x1a\x04\x90\xb5\x18\x01\x12.\n$MessageType_EthereumMessageSi\
\x10\xd0\x03\x1a\x04\x90\xb5\x18\x01\x125\n*MessageType_EthereumTypedDat\ gnature\x10B\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_EthereumSignType\
aStructRequest\x10\xd1\x03\x1a\x04\x98\xb5\x18\x01\x121\n&MessageType_Et\ dData\x10\xd0\x03\x1a\x04\x90\xb5\x18\x01\x125\n*MessageType_EthereumTyp\
hereumTypedDataStructAck\x10\xd2\x03\x1a\x04\x90\xb5\x18\x01\x124\n)Mess\ edDataStructRequest\x10\xd1\x03\x1a\x04\x98\xb5\x18\x01\x121\n&MessageTy\
ageType_EthereumTypedDataValueRequest\x10\xd3\x03\x1a\x04\x98\xb5\x18\ pe_EthereumTypedDataStructAck\x10\xd2\x03\x1a\x04\x90\xb5\x18\x01\x124\n\
\x01\x120\n%MessageType_EthereumTypedDataValueAck\x10\xd4\x03\x1a\x04\ )MessageType_EthereumTypedDataValueRequest\x10\xd3\x03\x1a\x04\x98\xb5\
\x90\xb5\x18\x01\x121\n&MessageType_EthereumTypedDataSignature\x10\xd5\ \x18\x01\x120\n%MessageType_EthereumTypedDataValueAck\x10\xd4\x03\x1a\
\x03\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_EthereumSignTypedHash\ \x04\x90\xb5\x18\x01\x121\n&MessageType_EthereumTypedDataSignature\x10\
\x10\xd6\x03\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_NEMGetAddress\ \xd5\x03\x1a\x04\x98\xb5\x18\x01\x12,\n!MessageType_EthereumSignTypedHas\
\x10C\x1a\x04\x90\xb5\x18\x01\x12\x20\n\x16MessageType_NEMAddress\x10D\ h\x10\xd6\x03\x1a\x04\x90\xb5\x18\x01\x12#\n\x19MessageType_NEMGetAddres\
s\x10C\x1a\x04\x90\xb5\x18\x01\x12\x20\n\x16MessageType_NEMAddress\x10D\
\x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_NEMSignTx\x10E\x1a\x04\ \x1a\x04\x98\xb5\x18\x01\x12\x1f\n\x15MessageType_NEMSignTx\x10E\x1a\x04\
\x90\xb5\x18\x01\x12!\n\x17MessageType_NEMSignedTx\x10F\x1a\x04\x98\xb5\ \x90\xb5\x18\x01\x12!\n\x17MessageType_NEMSignedTx\x10F\x1a\x04\x98\xb5\
\x18\x01\x12'\n\x1dMessageType_NEMDecryptMessage\x10K\x1a\x04\x90\xb5\ \x18\x01\x12'\n\x1dMessageType_NEMDecryptMessage\x10K\x1a\x04\x90\xb5\

View File

@ -2492,6 +2492,8 @@ pub mod features {
Capability_Solana = 18, Capability_Solana = 18,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.Features.Capability.Capability_Translations) // @@protoc_insertion_point(enum_value:hw.trezor.messages.management.Features.Capability.Capability_Translations)
Capability_Translations = 19, Capability_Translations = 19,
// @@protoc_insertion_point(enum_value:hw.trezor.messages.management.Features.Capability.Capability_Brightness)
Capability_Brightness = 20,
} }
impl ::protobuf::Enum for Capability { impl ::protobuf::Enum for Capability {
@ -2522,6 +2524,7 @@ pub mod features {
17 => ::std::option::Option::Some(Capability::Capability_PassphraseEntry), 17 => ::std::option::Option::Some(Capability::Capability_PassphraseEntry),
18 => ::std::option::Option::Some(Capability::Capability_Solana), 18 => ::std::option::Option::Some(Capability::Capability_Solana),
19 => ::std::option::Option::Some(Capability::Capability_Translations), 19 => ::std::option::Option::Some(Capability::Capability_Translations),
20 => ::std::option::Option::Some(Capability::Capability_Brightness),
_ => ::std::option::Option::None _ => ::std::option::Option::None
} }
} }
@ -2547,6 +2550,7 @@ pub mod features {
"Capability_PassphraseEntry" => ::std::option::Option::Some(Capability::Capability_PassphraseEntry), "Capability_PassphraseEntry" => ::std::option::Option::Some(Capability::Capability_PassphraseEntry),
"Capability_Solana" => ::std::option::Option::Some(Capability::Capability_Solana), "Capability_Solana" => ::std::option::Option::Some(Capability::Capability_Solana),
"Capability_Translations" => ::std::option::Option::Some(Capability::Capability_Translations), "Capability_Translations" => ::std::option::Option::Some(Capability::Capability_Translations),
"Capability_Brightness" => ::std::option::Option::Some(Capability::Capability_Brightness),
_ => ::std::option::Option::None _ => ::std::option::Option::None
} }
} }
@ -2571,6 +2575,7 @@ pub mod features {
Capability::Capability_PassphraseEntry, Capability::Capability_PassphraseEntry,
Capability::Capability_Solana, Capability::Capability_Solana,
Capability::Capability_Translations, Capability::Capability_Translations,
Capability::Capability_Brightness,
]; ];
} }
@ -2601,6 +2606,7 @@ pub mod features {
Capability::Capability_PassphraseEntry => 16, Capability::Capability_PassphraseEntry => 16,
Capability::Capability_Solana => 17, Capability::Capability_Solana => 17,
Capability::Capability_Translations => 18, Capability::Capability_Translations => 18,
Capability::Capability_Brightness => 19,
}; };
Self::enum_descriptor().value_by_index(index) Self::enum_descriptor().value_by_index(index)
} }
@ -10386,6 +10392,147 @@ impl ::protobuf::reflect::ProtobufValue for UnlockBootloader {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>; type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
} }
// @@protoc_insertion_point(message:hw.trezor.messages.management.SetBrightness)
#[derive(PartialEq,Clone,Default,Debug)]
pub struct SetBrightness {
// message fields
// @@protoc_insertion_point(field:hw.trezor.messages.management.SetBrightness.value)
pub value: ::std::option::Option<u32>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.management.SetBrightness.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
impl<'a> ::std::default::Default for &'a SetBrightness {
fn default() -> &'a SetBrightness {
<SetBrightness as ::protobuf::Message>::default_instance()
}
}
impl SetBrightness {
pub fn new() -> SetBrightness {
::std::default::Default::default()
}
// optional uint32 value = 1;
pub fn value(&self) -> u32 {
self.value.unwrap_or(0)
}
pub fn clear_value(&mut self) {
self.value = ::std::option::Option::None;
}
pub fn has_value(&self) -> bool {
self.value.is_some()
}
// Param is passed by value, moved
pub fn set_value(&mut self, v: u32) {
self.value = ::std::option::Option::Some(v);
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(1);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"value",
|m: &SetBrightness| { &m.value },
|m: &mut SetBrightness| { &mut m.value },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SetBrightness>(
"SetBrightness",
fields,
oneofs,
)
}
}
impl ::protobuf::Message for SetBrightness {
const NAME: &'static str = "SetBrightness";
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
while let Some(tag) = is.read_raw_tag_or_eof()? {
match tag {
8 => {
self.value = ::std::option::Option::Some(is.read_uint32()?);
},
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u64 {
let mut my_size = 0;
if let Some(v) = self.value {
my_size += ::protobuf::rt::uint32_size(1, v);
}
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
self.special_fields.cached_size().set(my_size as u32);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
if let Some(v) = self.value {
os.write_uint32(1, v)?;
}
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
fn special_fields(&self) -> &::protobuf::SpecialFields {
&self.special_fields
}
fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
&mut self.special_fields
}
fn new() -> SetBrightness {
SetBrightness::new()
}
fn clear(&mut self) {
self.value = ::std::option::Option::None;
self.special_fields.clear();
}
fn default_instance() -> &'static SetBrightness {
static instance: SetBrightness = SetBrightness {
value: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
}
}
impl ::protobuf::MessageFull for SetBrightness {
fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
descriptor.get(|| file_descriptor().message_by_package_relative_name("SetBrightness").unwrap()).clone()
}
}
impl ::std::fmt::Display for SetBrightness {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for SetBrightness {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)] #[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
// @@protoc_insertion_point(enum:hw.trezor.messages.management.BackupType) // @@protoc_insertion_point(enum:hw.trezor.messages.management.BackupType)
pub enum BackupType { pub enum BackupType {
@ -10612,7 +10759,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x0emessages.proto\"\x80\x01\n\nInitialize\x12\x1d\n\nsession_id\x18\x01\ \x0emessages.proto\"\x80\x01\n\nInitialize\x12\x1d\n\nsession_id\x18\x01\
\x20\x01(\x0cR\tsessionId\x12,\n\x10_skip_passphrase\x18\x02\x20\x01(\ \x20\x01(\x0cR\tsessionId\x12,\n\x10_skip_passphrase\x18\x02\x20\x01(\
\x08R\x0eSkipPassphraseB\x02\x18\x01\x12%\n\x0ederive_cardano\x18\x03\ \x08R\x0eSkipPassphraseB\x02\x18\x01\x12%\n\x0ederive_cardano\x18\x03\
\x20\x01(\x08R\rderiveCardano\"\r\n\x0bGetFeatures\"\xfa\x13\n\x08Featur\ \x20\x01(\x08R\rderiveCardano\"\r\n\x0bGetFeatures\"\x9b\x14\n\x08Featur\
es\x12\x16\n\x06vendor\x18\x01\x20\x01(\tR\x06vendor\x12#\n\rmajor_versi\ es\x12\x16\n\x06vendor\x18\x01\x20\x01(\tR\x06vendor\x12#\n\rmajor_versi\
on\x18\x02\x20\x02(\rR\x0cmajorVersion\x12#\n\rminor_version\x18\x03\x20\ on\x18\x02\x20\x02(\rR\x0cmajorVersion\x12#\n\rminor_version\x18\x03\x20\
\x02(\rR\x0cminorVersion\x12#\n\rpatch_version\x18\x04\x20\x02(\rR\x0cpa\ \x02(\rR\x0cminorVersion\x12#\n\rpatch_version\x18\x04\x20\x02(\rR\x0cpa\
@ -10657,7 +10804,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x180\x20\x01(\rR\x10homescreenHeight\x12+\n\x11bootloader_locked\x181\ \x180\x20\x01(\rR\x10homescreenHeight\x12+\n\x11bootloader_locked\x181\
\x20\x01(\x08R\x10bootloaderLocked\x12>\n\x18language_version_matches\ \x20\x01(\x08R\x10bootloaderLocked\x12>\n\x18language_version_matches\
\x182\x20\x01(\x08:\x04trueR\x16languageVersionMatches\x12%\n\x0eunit_pa\ \x182\x20\x01(\x08:\x04trueR\x16languageVersionMatches\x12%\n\x0eunit_pa\
ckaging\x183\x20\x01(\rR\runitPackaging\"\x84\x04\n\nCapability\x12\x1c\ ckaging\x183\x20\x01(\rR\runitPackaging\"\xa5\x04\n\nCapability\x12\x1c\
\n\x12Capability_Bitcoin\x10\x01\x1a\x04\x80\xa6\x1d\x01\x12\x1b\n\x17Ca\ \n\x12Capability_Bitcoin\x10\x01\x1a\x04\x80\xa6\x1d\x01\x12\x1b\n\x17Ca\
pability_Bitcoin_like\x10\x02\x12\x16\n\x12Capability_Binance\x10\x03\ pability_Bitcoin_like\x10\x02\x12\x16\n\x12Capability_Binance\x10\x03\
\x12\x16\n\x12Capability_Cardano\x10\x04\x12\x1b\n\x11Capability_Crypto\ \x12\x16\n\x12Capability_Cardano\x10\x04\x12\x1b\n\x11Capability_Crypto\
@ -10670,72 +10817,73 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x04\x80\xa6\x1d\x01\x12!\n\x17Capability_ShamirGroups\x10\x10\x1a\x04\ \x04\x80\xa6\x1d\x01\x12!\n\x17Capability_ShamirGroups\x10\x10\x1a\x04\
\x80\xa6\x1d\x01\x12$\n\x1aCapability_PassphraseEntry\x10\x11\x1a\x04\ \x80\xa6\x1d\x01\x12$\n\x1aCapability_PassphraseEntry\x10\x11\x1a\x04\
\x80\xa6\x1d\x01\x12\x15\n\x11Capability_Solana\x10\x12\x12!\n\x17Capabi\ \x80\xa6\x1d\x01\x12\x15\n\x11Capability_Solana\x10\x12\x12!\n\x17Capabi\
lity_Translations\x10\x13\x1a\x04\x80\xa6\x1d\x01\x1a\x04\xc8\xf3\x18\ lity_Translations\x10\x13\x1a\x04\x80\xa6\x1d\x01\x12\x1f\n\x15Capabilit\
\x01\"\x0c\n\nLockDevice\"&\n\x07SetBusy\x12\x1b\n\texpiry_ms\x18\x01\ y_Brightness\x10\x14\x1a\x04\x80\xa6\x1d\x01\x1a\x04\xc8\xf3\x18\x01\"\
\x20\x01(\rR\x08expiryMs\"\x0c\n\nEndSession\"\x9b\x04\n\rApplySettings\ \x0c\n\nLockDevice\"&\n\x07SetBusy\x12\x1b\n\texpiry_ms\x18\x01\x20\x01(\
\x12\x1e\n\x08language\x18\x01\x20\x01(\tR\x08languageB\x02\x18\x01\x12\ \rR\x08expiryMs\"\x0c\n\nEndSession\"\x9b\x04\n\rApplySettings\x12\x1e\n\
\x14\n\x05label\x18\x02\x20\x01(\tR\x05label\x12%\n\x0euse_passphrase\ \x08language\x18\x01\x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\x05l\
\x18\x03\x20\x01(\x08R\rusePassphrase\x12\x1e\n\nhomescreen\x18\x04\x20\ abel\x18\x02\x20\x01(\tR\x05label\x12%\n\x0euse_passphrase\x18\x03\x20\
\x01(\x0cR\nhomescreen\x120\n\x12_passphrase_source\x18\x05\x20\x01(\rR\ \x01(\x08R\rusePassphrase\x12\x1e\n\nhomescreen\x18\x04\x20\x01(\x0cR\nh\
\x10PassphraseSourceB\x02\x18\x01\x12+\n\x12auto_lock_delay_ms\x18\x06\ omescreen\x120\n\x12_passphrase_source\x18\x05\x20\x01(\rR\x10Passphrase\
\x20\x01(\rR\x0fautoLockDelayMs\x12)\n\x10display_rotation\x18\x07\x20\ SourceB\x02\x18\x01\x12+\n\x12auto_lock_delay_ms\x18\x06\x20\x01(\rR\x0f\
\x01(\rR\x0fdisplayRotation\x12=\n\x1bpassphrase_always_on_device\x18\ autoLockDelayMs\x12)\n\x10display_rotation\x18\x07\x20\x01(\rR\x0fdispla\
\x08\x20\x01(\x08R\x18passphraseAlwaysOnDevice\x12T\n\rsafety_checks\x18\ yRotation\x12=\n\x1bpassphrase_always_on_device\x18\x08\x20\x01(\x08R\
\t\x20\x01(\x0e2/.hw.trezor.messages.management.SafetyCheckLevelR\x0csaf\ \x18passphraseAlwaysOnDevice\x12T\n\rsafety_checks\x18\t\x20\x01(\x0e2/.\
etyChecks\x123\n\x15experimental_features\x18\n\x20\x01(\x08R\x14experim\ hw.trezor.messages.management.SafetyCheckLevelR\x0csafetyChecks\x123\n\
entalFeatures\x129\n\x19hide_passphrase_from_host\x18\x0b\x20\x01(\x08R\ \x15experimental_features\x18\n\x20\x01(\x08R\x14experimentalFeatures\
\x16hidePassphraseFromHost\"T\n\x0eChangeLanguage\x12\x1f\n\x0bdata_leng\ \x129\n\x19hide_passphrase_from_host\x18\x0b\x20\x01(\x08R\x16hidePassph\
th\x18\x01\x20\x02(\rR\ndataLength\x12!\n\x0cshow_display\x18\x02\x20\ raseFromHost\"T\n\x0eChangeLanguage\x12\x1f\n\x0bdata_length\x18\x01\x20\
\x01(\x08R\x0bshowDisplay\"Z\n\x16TranslationDataRequest\x12\x1f\n\x0bda\ \x02(\rR\ndataLength\x12!\n\x0cshow_display\x18\x02\x20\x01(\x08R\x0bsho\
ta_length\x18\x01\x20\x02(\rR\ndataLength\x12\x1f\n\x0bdata_offset\x18\ wDisplay\"Z\n\x16TranslationDataRequest\x12\x1f\n\x0bdata_length\x18\x01\
\x02\x20\x02(\rR\ndataOffset\"3\n\x12TranslationDataAck\x12\x1d\n\ndata_\ \x20\x02(\rR\ndataLength\x12\x1f\n\x0bdata_offset\x18\x02\x20\x02(\rR\nd\
chunk\x18\x01\x20\x02(\x0cR\tdataChunk\"\"\n\nApplyFlags\x12\x14\n\x05fl\ ataOffset\"3\n\x12TranslationDataAck\x12\x1d\n\ndata_chunk\x18\x01\x20\
ags\x18\x01\x20\x02(\rR\x05flags\"#\n\tChangePin\x12\x16\n\x06remove\x18\ \x02(\x0cR\tdataChunk\"\"\n\nApplyFlags\x12\x14\n\x05flags\x18\x01\x20\
\x01\x20\x01(\x08R\x06remove\"(\n\x0eChangeWipeCode\x12\x16\n\x06remove\ \x02(\rR\x05flags\"#\n\tChangePin\x12\x16\n\x06remove\x18\x01\x20\x01(\
\x18\x01\x20\x01(\x08R\x06remove\"\xaa\x01\n\tSdProtect\x12]\n\toperatio\ \x08R\x06remove\"(\n\x0eChangeWipeCode\x12\x16\n\x06remove\x18\x01\x20\
n\x18\x01\x20\x02(\x0e2?.hw.trezor.messages.management.SdProtect.SdProte\ \x01(\x08R\x06remove\"\xaa\x01\n\tSdProtect\x12]\n\toperation\x18\x01\
ctOperationTypeR\toperation\">\n\x16SdProtectOperationType\x12\x0b\n\x07\ \x20\x02(\x0e2?.hw.trezor.messages.management.SdProtect.SdProtectOperati\
DISABLE\x10\0\x12\n\n\x06ENABLE\x10\x01\x12\x0b\n\x07REFRESH\x10\x02\"O\ onTypeR\toperation\">\n\x16SdProtectOperationType\x12\x0b\n\x07DISABLE\
\n\x04Ping\x12\x1a\n\x07message\x18\x01\x20\x01(\t:\0R\x07message\x12+\n\ \x10\0\x12\n\n\x06ENABLE\x10\x01\x12\x0b\n\x07REFRESH\x10\x02\"O\n\x04Pi\
\x11button_protection\x18\x02\x20\x01(\x08R\x10buttonProtection\"\x08\n\ ng\x12\x1a\n\x07message\x18\x01\x20\x01(\t:\0R\x07message\x12+\n\x11butt\
\x06Cancel\"\x20\n\nGetEntropy\x12\x12\n\x04size\x18\x01\x20\x02(\rR\x04\ on_protection\x18\x02\x20\x01(\x08R\x10buttonProtection\"\x08\n\x06Cance\
size\"#\n\x07Entropy\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entro\ l\"\x20\n\nGetEntropy\x12\x12\n\x04size\x18\x01\x20\x02(\rR\x04size\"#\n\
py\"/\n\x0fGetFirmwareHash\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tc\ \x07Entropy\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entropy\"/\n\
hallenge\"\"\n\x0cFirmwareHash\x12\x12\n\x04hash\x18\x01\x20\x02(\x0cR\ \x0fGetFirmwareHash\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tchalleng\
\x04hash\"2\n\x12AuthenticateDevice\x12\x1c\n\tchallenge\x18\x01\x20\x02\ e\"\"\n\x0cFirmwareHash\x12\x12\n\x04hash\x18\x01\x20\x02(\x0cR\x04hash\
(\x0cR\tchallenge\"U\n\x11AuthenticityProof\x12\"\n\x0ccertificates\x18\ \"2\n\x12AuthenticateDevice\x12\x1c\n\tchallenge\x18\x01\x20\x02(\x0cR\t\
\x01\x20\x03(\x0cR\x0ccertificates\x12\x1c\n\tsignature\x18\x02\x20\x02(\ challenge\"U\n\x11AuthenticityProof\x12\"\n\x0ccertificates\x18\x01\x20\
\x0cR\tsignature\"\x0c\n\nWipeDevice\"\xad\x02\n\nLoadDevice\x12\x1c\n\t\ \x03(\x0cR\x0ccertificates\x12\x1c\n\tsignature\x18\x02\x20\x02(\x0cR\ts\
mnemonics\x18\x01\x20\x03(\tR\tmnemonics\x12\x10\n\x03pin\x18\x03\x20\ ignature\"\x0c\n\nWipeDevice\"\xad\x02\n\nLoadDevice\x12\x1c\n\tmnemonic\
\x01(\tR\x03pin\x123\n\x15passphrase_protection\x18\x04\x20\x01(\x08R\ s\x18\x01\x20\x03(\tR\tmnemonics\x12\x10\n\x03pin\x18\x03\x20\x01(\tR\
\x14passphraseProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08la\ \x03pin\x123\n\x15passphrase_protection\x18\x04\x20\x01(\x08R\x14passphr\
nguageB\x02\x18\x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12#\ aseProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08languageB\x02\
\n\rskip_checksum\x18\x07\x20\x01(\x08R\x0cskipChecksum\x12\x1f\n\x0bu2f\ \x18\x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12#\n\rskip_ch\
_counter\x18\x08\x20\x01(\rR\nu2fCounter\x12!\n\x0cneeds_backup\x18\t\ ecksum\x18\x07\x20\x01(\x08R\x0cskipChecksum\x12\x1f\n\x0bu2f_counter\
\x20\x01(\x08R\x0bneedsBackup\x12\x1b\n\tno_backup\x18\n\x20\x01(\x08R\ \x18\x08\x20\x01(\rR\nu2fCounter\x12!\n\x0cneeds_backup\x18\t\x20\x01(\
\x08noBackup\"\x99\x03\n\x0bResetDevice\x12%\n\x0edisplay_random\x18\x01\ \x08R\x0bneedsBackup\x12\x1b\n\tno_backup\x18\n\x20\x01(\x08R\x08noBacku\
\x20\x01(\x08R\rdisplayRandom\x12\x1f\n\x08strength\x18\x02\x20\x01(\r:\ p\"\x99\x03\n\x0bResetDevice\x12%\n\x0edisplay_random\x18\x01\x20\x01(\
\x03256R\x08strength\x123\n\x15passphrase_protection\x18\x03\x20\x01(\ \x08R\rdisplayRandom\x12\x1f\n\x08strength\x18\x02\x20\x01(\r:\x03256R\
\x08R\x14passphraseProtection\x12%\n\x0epin_protection\x18\x04\x20\x01(\ \x08strength\x123\n\x15passphrase_protection\x18\x03\x20\x01(\x08R\x14pa\
\x08R\rpinProtection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08langua\ ssphraseProtection\x12%\n\x0epin_protection\x18\x04\x20\x01(\x08R\rpinPr\
geB\x02\x18\x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12\x1f\ otection\x12\x1e\n\x08language\x18\x05\x20\x01(\tR\x08languageB\x02\x18\
\n\x0bu2f_counter\x18\x07\x20\x01(\rR\nu2fCounter\x12\x1f\n\x0bskip_back\ \x01\x12\x14\n\x05label\x18\x06\x20\x01(\tR\x05label\x12\x1f\n\x0bu2f_co\
up\x18\x08\x20\x01(\x08R\nskipBackup\x12\x1b\n\tno_backup\x18\t\x20\x01(\ unter\x18\x07\x20\x01(\rR\nu2fCounter\x12\x1f\n\x0bskip_backup\x18\x08\
\x08R\x08noBackup\x12Q\n\x0bbackup_type\x18\n\x20\x01(\x0e2).hw.trezor.m\ \x20\x01(\x08R\nskipBackup\x12\x1b\n\tno_backup\x18\t\x20\x01(\x08R\x08n\
essages.management.BackupType:\x05Bip39R\nbackupType\"\xe5\x01\n\x0cBack\ oBackup\x12Q\n\x0bbackup_type\x18\n\x20\x01(\x0e2).hw.trezor.messages.ma\
upDevice\x12'\n\x0fgroup_threshold\x18\x01\x20\x01(\rR\x0egroupThreshold\ nagement.BackupType:\x05Bip39R\nbackupType\"\xe5\x01\n\x0cBackupDevice\
\x12O\n\x06groups\x18\x02\x20\x03(\x0b27.hw.trezor.messages.management.B\ \x12'\n\x0fgroup_threshold\x18\x01\x20\x01(\rR\x0egroupThreshold\x12O\n\
ackupDevice.Slip39GroupR\x06groups\x1a[\n\x0bSlip39Group\x12)\n\x10membe\ \x06groups\x18\x02\x20\x03(\x0b27.hw.trezor.messages.management.BackupDe\
r_threshold\x18\x01\x20\x02(\rR\x0fmemberThreshold\x12!\n\x0cmember_coun\ vice.Slip39GroupR\x06groups\x1a[\n\x0bSlip39Group\x12)\n\x10member_thres\
t\x18\x02\x20\x02(\rR\x0bmemberCount\"\x10\n\x0eEntropyRequest\"&\n\nEnt\ hold\x18\x01\x20\x02(\rR\x0fmemberThreshold\x12!\n\x0cmember_count\x18\
ropyAck\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entropy\"\xd8\x03\ \x02\x20\x02(\rR\x0bmemberCount\"\x10\n\x0eEntropyRequest\"&\n\nEntropyA\
\n\x0eRecoveryDevice\x12\x1d\n\nword_count\x18\x01\x20\x01(\rR\twordCoun\ ck\x12\x18\n\x07entropy\x18\x01\x20\x02(\x0cR\x07entropy\"\xd8\x03\n\x0e\
t\x123\n\x15passphrase_protection\x18\x02\x20\x01(\x08R\x14passphrasePro\ RecoveryDevice\x12\x1d\n\nword_count\x18\x01\x20\x01(\rR\twordCount\x123\
tection\x12%\n\x0epin_protection\x18\x03\x20\x01(\x08R\rpinProtection\ \n\x15passphrase_protection\x18\x02\x20\x01(\x08R\x14passphraseProtectio\
\x12\x1e\n\x08language\x18\x04\x20\x01(\tR\x08languageB\x02\x18\x01\x12\ n\x12%\n\x0epin_protection\x18\x03\x20\x01(\x08R\rpinProtection\x12\x1e\
\x14\n\x05label\x18\x05\x20\x01(\tR\x05label\x12)\n\x10enforce_wordlist\ \n\x08language\x18\x04\x20\x01(\tR\x08languageB\x02\x18\x01\x12\x14\n\
\x18\x06\x20\x01(\x08R\x0fenforceWordlist\x12T\n\x04type\x18\x08\x20\x01\ \x05label\x18\x05\x20\x01(\tR\x05label\x12)\n\x10enforce_wordlist\x18\
(\x0e2@.hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceTypeR\ \x06\x20\x01(\x08R\x0fenforceWordlist\x12T\n\x04type\x18\x08\x20\x01(\
\x0e2@.hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceTypeR\
\x04type\x12\x1f\n\x0bu2f_counter\x18\t\x20\x01(\rR\nu2fCounter\x12\x17\ \x04type\x12\x1f\n\x0bu2f_counter\x18\t\x20\x01(\rR\nu2fCounter\x12\x17\
\n\x07dry_run\x18\n\x20\x01(\x08R\x06dryRun\"Z\n\x12RecoveryDeviceType\ \n\x07dry_run\x18\n\x20\x01(\x08R\x06dryRun\"Z\n\x12RecoveryDeviceType\
\x12%\n!RecoveryDeviceType_ScrambledWords\x10\0\x12\x1d\n\x19RecoveryDev\ \x12%\n!RecoveryDeviceType_ScrambledWords\x10\0\x12\x1d\n\x19RecoveryDev\
@ -10759,15 +10907,15 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\ \x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x10\n\x03mac\x18\
\x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\n\x03mac\ \x02\x20\x01(\x0cR\x03mac\"'\n\x13UnlockedPathRequest\x12\x10\n\x03mac\
\x18\x01\x20\x01(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10U\ \x18\x01\x20\x01(\x0cR\x03mac\"\x14\n\x12ShowDeviceTutorial\"\x12\n\x10U\
nlockBootloader*\x99\x01\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\ nlockBootloader\"%\n\rSetBrightness\x12\x14\n\x05value\x18\x01\x20\x01(\
\x0cSlip39_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\ \rR\x05value*\x99\x01\n\nBackupType\x12\t\n\x05Bip39\x10\0\x12\x10\n\x0c\
\x18Slip39_Single_Extendable\x10\x03\x12\x1b\n\x17Slip39_Basic_Extendabl\ Slip39_Basic\x10\x01\x12\x13\n\x0fSlip39_Advanced\x10\x02\x12\x1c\n\x18S\
e\x10\x04\x12\x1e\n\x1aSlip39_Advanced_Extendable\x10\x05*G\n\x10SafetyC\ lip39_Single_Extendable\x10\x03\x12\x1b\n\x17Slip39_Basic_Extendable\x10\
heckLevel\x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\ \x04\x12\x1e\n\x1aSlip39_Advanced_Extendable\x10\x05*G\n\x10SafetyCheckL\
\x15\n\x11PromptTemporarily\x10\x02*0\n\x10HomescreenFormat\x12\x08\n\ evel\x12\n\n\x06Strict\x10\0\x12\x10\n\x0cPromptAlways\x10\x01\x12\x15\n\
\x04Toif\x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03BB\n\ \x11PromptTemporarily\x10\x02*0\n\x10HomescreenFormat\x12\x08\n\x04Toif\
#com.satoshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\x80\xa6\ \x10\x01\x12\x08\n\x04Jpeg\x10\x02\x12\x08\n\x04ToiG\x10\x03BB\n#com.sat\
\x1d\x01\ oshilabs.trezor.lib.protobufB\x17TrezorMessageManagement\x80\xa6\x1d\x01\
"; ";
/// `FileDescriptorProto` object which was a source for this generated file /// `FileDescriptorProto` object which was a source for this generated file
@ -10786,7 +10934,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
let mut deps = ::std::vec::Vec::with_capacity(1); let mut deps = ::std::vec::Vec::with_capacity(1);
deps.push(super::messages::file_descriptor().clone()); deps.push(super::messages::file_descriptor().clone());
let mut messages = ::std::vec::Vec::with_capacity(45); let mut messages = ::std::vec::Vec::with_capacity(46);
messages.push(Initialize::generated_message_descriptor_data()); messages.push(Initialize::generated_message_descriptor_data());
messages.push(GetFeatures::generated_message_descriptor_data()); messages.push(GetFeatures::generated_message_descriptor_data());
messages.push(Features::generated_message_descriptor_data()); messages.push(Features::generated_message_descriptor_data());
@ -10831,6 +10979,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
messages.push(UnlockedPathRequest::generated_message_descriptor_data()); messages.push(UnlockedPathRequest::generated_message_descriptor_data());
messages.push(ShowDeviceTutorial::generated_message_descriptor_data()); messages.push(ShowDeviceTutorial::generated_message_descriptor_data());
messages.push(UnlockBootloader::generated_message_descriptor_data()); messages.push(UnlockBootloader::generated_message_descriptor_data());
messages.push(SetBrightness::generated_message_descriptor_data());
messages.push(backup_device::Slip39Group::generated_message_descriptor_data()); messages.push(backup_device::Slip39Group::generated_message_descriptor_data());
let mut enums = ::std::vec::Vec::with_capacity(8); let mut enums = ::std::vec::Vec::with_capacity(8);
enums.push(BackupType::generated_enum_descriptor_data()); enums.push(BackupType::generated_enum_descriptor_data());