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

feat(core): Implement SetBusy message.

This commit is contained in:
Andrew Kozlik 2022-08-09 18:26:37 +02:00 committed by Andrew Kozlik
parent 792dadfc4d
commit d089fd3187
5 changed files with 80 additions and 1 deletions

View File

@ -0,0 +1 @@
Support SetBusy message.

View File

@ -351,6 +351,8 @@ apps.debug.load_device
import apps.debug.load_device
apps.homescreen
import apps.homescreen
apps.homescreen.busyscreen
import apps.homescreen.busyscreen
apps.homescreen.homescreen
import apps.homescreen.homescreen
apps.homescreen.lockscreen

View File

@ -20,9 +20,26 @@ if TYPE_CHECKING:
Ping,
DoPreauthorized,
CancelAuthorization,
SetBusy,
)
def busy_expiry_ms() -> int:
"""
Returns the time left until the busy state expires or 0 if the device is not in the busy state.
"""
busy_deadline_bytes = storage.cache.get(storage.cache.APP_COMMON_BUSY_DEADLINE_MS)
if busy_deadline_bytes is None:
return 0
import utime
busy_deadline_ms = int.from_bytes(busy_deadline_bytes, "big")
expiry_ms = utime.ticks_diff(busy_deadline_ms, utime.ticks_ms())
return expiry_ms if expiry_ms > 0 else 0
def get_features() -> Features:
import storage.recovery
import storage.sd_salt
@ -47,6 +64,7 @@ def get_features() -> Features:
label=storage.device.get_label(),
pin_protection=config.has_pin(),
unlocked=config.is_unlocked(),
busy=busy_expiry_ms() > 0,
)
if utils.BITCOIN_ONLY:
@ -145,6 +163,24 @@ async def handle_LockDevice(ctx: wire.Context, msg: LockDevice) -> Success:
return Success()
async def handle_SetBusy(ctx: wire.Context, msg: SetBusy) -> Success:
if not storage.device.is_initialized():
raise wire.NotInitialized("Device is not initialized")
if msg.expiry_ms:
import utime
deadline = utime.ticks_add(utime.ticks_ms(), msg.expiry_ms)
storage.cache.set(
storage.cache.APP_COMMON_BUSY_DEADLINE_MS, deadline.to_bytes(4, "big")
)
else:
storage.cache.delete(storage.cache.APP_COMMON_BUSY_DEADLINE_MS)
set_homescreen()
workflow.close_others()
return Success()
async def handle_EndSession(ctx: wire.Context, msg: EndSession) -> Success:
storage.cache.end_current_session()
return Success()
@ -200,13 +236,20 @@ ALLOW_WHILE_LOCKED = (
MessageType.LockDevice,
MessageType.DoPreauthorized,
MessageType.WipeDevice,
MessageType.SetBusy,
)
def set_homescreen() -> None:
import storage.recovery
import storage # workaround for https://github.com/microsoft/pyright/issues/2685
if not config.is_unlocked():
if storage.cache.is_set(storage.cache.APP_COMMON_BUSY_DEADLINE_MS):
from apps.homescreen.busyscreen import busyscreen
workflow.set_default(busyscreen)
elif not config.is_unlocked():
from apps.homescreen.lockscreen import lockscreen
workflow.set_default(lockscreen)
@ -296,6 +339,7 @@ def boot() -> None:
workflow_handlers.register(
MessageType.CancelAuthorization, handle_CancelAuthorization
)
workflow_handlers.register(MessageType.SetBusy, handle_SetBusy)
reload_settings_from_storage()
if config.is_unlocked():

View File

@ -0,0 +1,29 @@
import storage.cache
from trezor import loop, ui
from trezor.ui.layouts import draw_simple_text
from apps.base import busy_expiry_ms, set_homescreen
from . import HomescreenBase
async def busyscreen() -> None:
await Busyscreen()
class Busyscreen(HomescreenBase):
RENDER_INDICATOR = storage.cache.BUSYSCREEN_ON
def create_tasks(self) -> tuple[loop.AwaitableTask, ...]:
return self.handle_rendering(), self.handle_input(), self.handle_expiry()
def handle_expiry(self) -> loop.Task: # type: ignore [awaitable-is-generator]
yield loop.sleep(busy_expiry_ms())
storage.cache.delete(storage.cache.APP_COMMON_BUSY_DEADLINE_MS)
set_homescreen()
raise ui.Result(None)
def do_render(self) -> None:
draw_simple_text(
"Please wait", "CoinJoin in progress.\n\nDo not disconnect your\nTrezor."
)

View File

@ -30,6 +30,7 @@ APP_COMMON_SEED_WITHOUT_PASSPHRASE = 0 | _SESSIONLESS_FLAG
APP_COMMON_SAFETY_CHECKS_TEMPORARY = 1 | _SESSIONLESS_FLAG
STORAGE_DEVICE_EXPERIMENTAL_FEATURES = 2 | _SESSIONLESS_FLAG
APP_COMMON_REQUEST_PIN_LAST_UNLOCK = 3 | _SESSIONLESS_FLAG
APP_COMMON_BUSY_DEADLINE_MS = 4 | _SESSIONLESS_FLAG
# === Homescreen storage ===
@ -40,6 +41,7 @@ APP_COMMON_REQUEST_PIN_LAST_UNLOCK = 3 | _SESSIONLESS_FLAG
# is still on. This way we can avoid unnecessary fadeins/fadeouts when a workflow ends.
HOMESCREEN_ON = object()
LOCKSCREEN_ON = object()
BUSYSCREEN_ON = object()
homescreen_shown: object | None = None
@ -132,6 +134,7 @@ class SessionlessCache(DataCache):
1, # APP_COMMON_SAFETY_CHECKS_TEMPORARY
1, # STORAGE_DEVICE_EXPERIMENTAL_FEATURES
4, # APP_COMMON_REQUEST_PIN_LAST_UNLOCK
4, # APP_COMMON_BUSY_DEADLINE_MS
)
super().__init__()