chore(core/eckhart): update device menu device settings
What changed, and why it matters
This commit is a routine UI update for the Trezor hardware wallet's device menu. It wires up previously placeholder settings (screen brightness, haptic feedback) and adds a 'Wipe device' option to the menu. There is no security fix or vulnerability visible in the change.
No security action required; treat as normal feature/UI commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch updates the Eckhart layout’s device menu screen in Rust and its Python homescreen controller. It replaces stubbed TODO values with real storage-backed values for screen brightness and haptic feedback, adds a wipe-device menu item styled as a warning, and implements handlers that call existing management functions (set_brightness, apply_settings). The auto-lock delay parameter is no longer passed to the device menu screen. No cryptographic, authorization, or input-validation changes are present.
Changed components
core/embed/rust/src/ui/layout_eckhart/firmware/device_menu_screen.rscore/src/apps/homescreen/device_menu.pyInspect captured patch +72 / −29
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/device_menu_screen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/device_menu_screen.rs
index 55bd62ef..3da77624 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/device_menu_screen.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/device_menu_screen.rs
@@ -100,6 +100,7 @@ struct MenuItem {
action: Option<Action>,
}
const MENU_ITEM_TITLE_STYLE_SHEET: &ButtonStyleSheet = &theme::menu_item_title();
+const MENU_ITEM_WARNING: &ButtonStyleSheet = &theme::menu_item_title_orange();
impl MenuItem {
pub fn new(text: TString<'static>, action: Option<Action>) -> Self {
@@ -197,12 +198,12 @@ impl DeviceMenuScreen {
_connected_idx: Option<usize>,
_bluetooth: Option<bool>,
_pin_code: Option<bool>,
- auto_lock_delay: Option<TString<'static>>,
+ _auto_lock_delay: Option<TString<'static>>,
_wipe_code: Option<bool>,
_check_backup: bool,
device_name: Option<TString<'static>>,
- _screen_brightness: Option<TString<'static>>,
- _haptic_feedback: Option<bool>,
+ screen_brightness: Option<TString<'static>>,
+ haptic_feedback: Option<bool>,
led_enabled: Option<bool>,
about_items: Obj,
) -> Result<Self, Error> {
@@ -219,8 +220,14 @@ impl DeviceMenuScreen {
let about = screen.add_subscreen(Subscreen::AboutScreen);
let regulatory = screen.add_subscreen(Subscreen::RegulatoryScreen);
let security = screen.add_security_menu();
- let device =
- screen.add_device_menu(device_name, regulatory, about, auto_lock_delay, led_enabled);
+ let device = screen.add_device_menu(
+ device_name,
+ screen_brightness,
+ haptic_feedback,
+ led_enabled,
+ regulatory,
+ about,
+ );
let settings = screen.add_settings_menu(security, device);
let is_connected = !paired_devices.is_empty(); // FIXME after BLE API has this
@@ -320,10 +327,11 @@ impl DeviceMenuScreen {
fn add_device_menu(
&mut self,
device_name: Option<TString<'static>>,
+ screen_brightness: Option<TString<'static>>,
+ haptic_feedback: Option<bool>,
+ led_enabled: Option<bool>,
regulatory_index: usize,
about_index: usize,
- auto_lock_delay: Option<TString<'static>>,
- led_enabled: Option<bool>,
) -> usize {
let mut items: Vec<MenuItem, MEDIUM_MENU_ITEMS> = Vec::new();
if let Some(device_name) = device_name {
@@ -335,18 +343,28 @@ impl DeviceMenuScreen {
unwrap!(items.push(item_device_name));
}
- unwrap!(items.push(MenuItem::new(
- TR::brightness__title.into(),
- Some(Action::Return(DeviceMenuMsg::ScreenBrightness)),
- )));
+ if let Some(brightness) = screen_brightness {
+ let brightness_item = MenuItem::new(
+ brightness,
+ Some(Action::Return(DeviceMenuMsg::ScreenBrightness)),
+ );
+ unwrap!(items.push(brightness_item));
+ }
- if let Some(auto_lock_delay) = auto_lock_delay {
- let mut autolock_delay_item = MenuItem::new(
- TR::auto_lock__title.into(),
- Some(Action::Return(DeviceMenuMsg::AutoLockDelay)),
+ if let Some(haptic_feedback) = haptic_feedback {
+ let mut haptic_item = MenuItem::new(
+ TR::haptic_feedback__title.into(),
+ Some(Action::Return(DeviceMenuMsg::HapticFeedback)),
);
- autolock_delay_item.with_subtext(Some((auto_lock_delay, None)));
- unwrap!(items.push(autolock_delay_item));
+ let subtext = match haptic_feedback {
+ true => (
+ TR::words__on.into(),
+ Some(&theme::TEXT_MENU_ITEM_SUBTITLE_GREEN),
+ ),
+ _ => (TR::words__off.into(), None),
+ };
+ haptic_item.with_subtext(Some(subtext));
+ unwrap!(items.push(haptic_item));
}
if let Some(led_enabled) = led_enabled {
@@ -375,6 +393,13 @@ impl DeviceMenuScreen {
Some(Action::GoTo(about_index))
)));
+ let mut wipe_device_item = MenuItem::new(
+ TR::wipe__title.into(),
+ Some(Action::Return(DeviceMenuMsg::WipeDevice)),
+ );
+ wipe_device_item.with_stylesheet(MENU_ITEM_WARNING);
+ unwrap!(items.push(wipe_device_item));
+
let submenu_index = self.add_submenu(Submenu::new(items));
self.add_subscreen(Subscreen::Submenu(submenu_index))
}
diff --git a/core/src/apps/homescreen/device_menu.py b/core/src/apps/homescreen/device_menu.py
index ae56c9f8..abea118e 100644
--- a/core/src/apps/homescreen/device_menu.py
+++ b/core/src/apps/homescreen/device_menu.py
@@ -37,15 +37,10 @@ async def handle_device_menu() -> None:
)
# MOCK DATA
paired_devices = ["Trezor Suite"] if ble.is_connected() else []
+ bluetooth_version = "2.3.1.1"
# ###
firmware_version = ".".join(map(str, utils.VERSION))
firmware_type = "Bitcoin-only" if utils.BITCOIN_ONLY else "Universal"
- device_name = (
- (storage_device.get_label() or "Trezor")
- if storage_device.is_initialized()
- else None
- )
- bluetooth_version = "2.3.1.1"
auto_lock_ms = storage_device.get_autolock_delay_ms()
auto_lock_delay = strings.format_autolock_duration(auto_lock_ms)
@@ -64,11 +59,21 @@ async def handle_device_menu() -> None:
bluetooth=None, # TODO implement
pin_code=None, # TODO implement
auto_lock_delay=auto_lock_delay,
- wipe_code=False, # TODO implement
+ wipe_code=None, # TODO implement
check_backup=False, # TODO implement
- device_name=device_name,
- screen_brightness=None, # TODO implement
- haptic_feedback=None, # TODO implement
+ device_name=(
+ (storage_device.get_label() or "Trezor")
+ if storage_device.is_initialized()
+ else None
+ ),
+ screen_brightness=(
+ TR.brightness__title if storage_device.is_initialized() else None
+ ),
+ haptic_feedback=(
+ storage_device.get_haptic_feedback()
+ if (storage_device.is_initialized() and utils.USE_HAPTIC)
+ else None
+ ),
led_enabled=(
storage_device.get_rgb_led()
if (storage_device.is_initialized() and utils.USE_RGB_LED)
@@ -141,9 +146,22 @@ async def handle_device_menu() -> None:
assert isinstance(label, str)
await apply_settings(ApplySettings(label=label))
elif menu_result is DeviceMenuResult.ScreenBrightness:
- pass # TODO implement screen brightness handling
+ from trezor.messages import SetBrightness
+
+ from apps.management.set_brightness import set_brightness
+
+ await set_brightness(SetBrightness())
elif menu_result is DeviceMenuResult.HapticFeedback:
- pass # TODO implement haptic feedback handling
+ from trezor.messages import ApplySettings
+
+ from apps.management.apply_settings import apply_settings
+
+ assert storage_device.is_initialized()
+ await apply_settings(
+ ApplySettings(
+ haptic_feedback=not storage_device.get_haptic_feedback(),
+ )
+ )
elif menu_result is DeviceMenuResult.LedEnabled:
from trezor import io
from trezor.ui.layouts import confirm_action
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.