You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/homescreen/homescreen.py

93 lines
3.0 KiB

import utime
from micropython import const
import storage
import storage.device
from trezor import config, ui
from trezor.ui.loader import Loader, LoaderNeutral
from apps.base import lock_device
from . import HomescreenBase
_LOADER_DELAY_MS = const(500)
_LOADER_TOTAL_MS = const(2500)
async def homescreen() -> None:
await Homescreen()
lock_device()
class Homescreen(HomescreenBase):
def __init__(self) -> None:
super().__init__()
if not storage.device.is_initialized():
self.label = "Go to trezor.io/start"
self.loader = Loader(
style=LoaderNeutral,
target_ms=_LOADER_TOTAL_MS - _LOADER_DELAY_MS,
offset_y=-10,
reverse_speedup=3,
)
self.touch_ms: int | None = None
def on_render(self) -> None:
if not self.repaint:
return
# warning bar on top
if storage.device.is_initialized() and storage.device.no_backup():
ui.header_error("SEEDLESS")
elif storage.device.is_initialized() and storage.device.unfinished_backup():
ui.header_error("BACKUP FAILED!")
elif storage.device.is_initialized() and storage.device.needs_backup():
ui.header_warning("NEEDS BACKUP!")
elif storage.device.is_initialized() and not config.has_pin():
ui.header_warning("PIN NOT SET!")
elif storage.device.get_experimental_features():
ui.header_warning("EXPERIMENTAL MODE!")
else:
ui.display.bar(0, 0, ui.WIDTH, ui.HEIGHT, ui.BG)
# homescreen with shifted avatar and text on bottom
ui.display.avatar(48, 48 - 10, self.image, ui.WHITE, ui.BLACK)
ui.display.text_center(ui.WIDTH // 2, 220, self.label, ui.BOLD, ui.FG, ui.BG)
self.repaint = False
def on_touch_start(self, _x: int, _y: int) -> None:
if self.loader.start_ms is not None:
self.loader.start()
elif config.has_pin():
self.touch_ms = utime.ticks_ms()
def on_touch_end(self, _x: int, _y: int) -> None:
if self.loader.start_ms is not None:
self.repaint = True
self.loader.stop()
self.touch_ms = None
# raise here instead of self.loader.on_finish so as not to send TOUCH_END to the lockscreen
if self.loader.elapsed_ms() >= self.loader.target_ms:
raise ui.Result(None)
def _loader_start(self) -> None:
ui.display.clear()
ui.display.text_center(ui.WIDTH // 2, 35, "Hold to lock", ui.BOLD, ui.FG, ui.BG)
self.loader.start()
def dispatch(self, event: int, x: int, y: int) -> None:
if (
self.touch_ms is not None
and self.touch_ms + _LOADER_DELAY_MS < utime.ticks_ms()
):
self.touch_ms = None
self._loader_start()
if event is ui.RENDER and self.loader.start_ms is not None:
self.loader.dispatch(event, x, y)
else:
super().dispatch(event, x, y)