Skip to content

Commit 050eaea

Browse files
committed
feat(core): handle power button in FW loop
- power button is handled before the event is passed to rust layouts [no changelog]
1 parent 2ace321 commit 050eaea

File tree

2 files changed

+57
-20
lines changed

2 files changed

+57
-20
lines changed

core/src/apps/base.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import storage.device as storage_device
44
from storage.cache_common import APP_COMMON_BUSY_DEADLINE_MS, APP_COMMON_SEED
5-
from trezor import TR, config, utils, wire, workflow
5+
from trezor import TR, config, io, utils, wire, workflow
66
from trezor.enums import HomescreenFormat, MessageType
77
from trezor.messages import Success, UnlockPath
88
from trezor.ui.layouts import confirm_action
@@ -396,6 +396,18 @@ def set_homescreen() -> None:
396396
set_default(homescreen)
397397

398398

399+
if utils.USE_POWER_MANAGER:
400+
401+
def suspend_device() -> None:
402+
"""Suspends the device when the power button is pressed."""
403+
if config.has_pin() and config.is_unlocked():
404+
lock_device(interrupt_workflow=True)
405+
else:
406+
set_homescreen()
407+
workflow.close_others()
408+
io.pm.suspend()
409+
410+
399411
def lock_device(interrupt_workflow: bool = True) -> None:
400412
if config.has_pin():
401413
config.lock()

core/src/trezor/ui/__init__.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -374,34 +374,59 @@ def create_tasks(self) -> Iterator[loop.Task]:
374374
"""Set up background tasks for a layout.
375375
376376
Called from `start()`. Creates and yields a list of background tasks, typically
377-
event handlers for different interfaces.
377+
event handlers for different interfaces. Event handlers are enabled based on build options to prevent keeping stale events in the event queue.
378378
379379
Override and then `yield from super().create_tasks()` to add more tasks."""
380380
if utils.USE_BUTTON:
381-
yield self._handle_input_iface(io.BUTTON, self.layout.button_event)
381+
yield self._handle_button_events()
382382
if utils.USE_TOUCH:
383-
yield self._handle_input_iface(io.TOUCH, self.layout.touch_event)
383+
yield self._handle_touch_events()
384384
if utils.USE_BLE:
385-
# most layouts don't care but we don't want to keep stale events in the queue
386385
yield self._handle_ble_events()
387386
if utils.USE_POWER_MANAGER:
388387
yield self._handle_power_manager()
389388

390-
def _handle_input_iface(
391-
self, iface: int, event_call: Callable[..., LayoutState | None]
392-
) -> Generator:
393-
"""Task that is waiting for the user input."""
394-
touch = loop.wait(iface)
395-
try:
396-
while True:
397-
# Using `yield` instead of `await` to avoid allocations.
398-
event = yield touch
399-
workflow.idle_timer.touch()
400-
self._event(event_call, *event)
401-
except Shutdown:
402-
return
403-
finally:
404-
touch.close()
389+
if utils.USE_BUTTON:
390+
391+
def _handle_button_events(self) -> Generator:
392+
"""Task that is waiting for the user button input."""
393+
button = loop.wait(io.BUTTON)
394+
try:
395+
while True:
396+
# Using `yield` instead of `await` to avoid allocations.
397+
event = yield button
398+
if utils.USE_POWER_MANAGER:
399+
event_type, event_button = event
400+
# check for POWER_BUTTON (2), BUTTON_UP (0)
401+
if event_button == 2 and event_type == 0:
402+
from apps.base import suspend_device
403+
404+
if __debug__:
405+
log.info(__name__, "suspend_device")
406+
suspend_device()
407+
break
408+
workflow.idle_timer.touch()
409+
self._event(self.layout.button_event, *event)
410+
except Shutdown:
411+
return
412+
finally:
413+
button.close()
414+
415+
if utils.USE_TOUCH:
416+
417+
def _handle_touch_events(self) -> Generator:
418+
"""Task that is waiting for the user touch input."""
419+
touch = loop.wait(io.TOUCH)
420+
try:
421+
while True:
422+
# Using `yield` instead of `await` to avoid allocations.
423+
event = yield touch
424+
workflow.idle_timer.touch()
425+
self._event(self.layout.touch_event, *event)
426+
except Shutdown:
427+
return
428+
finally:
429+
touch.close()
405430

406431
async def _handle_usb_iface(self) -> None:
407432
if self.context is None:

0 commit comments

Comments
 (0)