mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-18 05:28:40 +00:00
core: replace workflow.kill_default with workflow.close_others
This commit is contained in:
parent
3c128cde38
commit
f32c2f9e23
@ -57,9 +57,8 @@ def get_seed(passphrase: str = "", progress_bar: bool = True) -> bytes:
|
|||||||
|
|
||||||
def _start_progress() -> None:
|
def _start_progress() -> None:
|
||||||
# Because we are drawing to the screen manually, without a layout, we
|
# Because we are drawing to the screen manually, without a layout, we
|
||||||
# should make sure that no other layout is running. At this point, only
|
# should make sure that no other layout is running.
|
||||||
# the homescreen should be on, so shut it down.
|
workflow.close_others()
|
||||||
workflow.kill_default()
|
|
||||||
t = Text("Please wait", ui.ICON_CONFIG)
|
t = Text("Please wait", ui.ICON_CONFIG)
|
||||||
ui.draw_simple(t)
|
ui.draw_simple(t)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ async def get(ctx: wire.Context) -> str:
|
|||||||
|
|
||||||
|
|
||||||
async def _request_from_user(ctx: wire.Context) -> str:
|
async def _request_from_user(ctx: wire.Context) -> str:
|
||||||
|
workflow.close_others() # request exclusive UI access
|
||||||
if storage.device.get_passphrase_always_on_device():
|
if storage.device.get_passphrase_always_on_device():
|
||||||
passphrase = await _request_on_device(ctx)
|
passphrase = await _request_on_device(ctx)
|
||||||
else:
|
else:
|
||||||
@ -69,7 +70,6 @@ async def _request_on_device(ctx: wire.Context) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _entry_dialog() -> None:
|
def _entry_dialog() -> None:
|
||||||
workflow.kill_default()
|
|
||||||
text = Text("Passphrase entry", ICON_CONFIG)
|
text = Text("Passphrase entry", ICON_CONFIG)
|
||||||
text.normal("Please type your", "passphrase on the", "connected host.")
|
text.normal("Please type your", "passphrase on the", "connected host.")
|
||||||
draw_simple(text)
|
draw_simple(text)
|
||||||
|
@ -168,7 +168,8 @@ def draw_simple(t: Component) -> None: # noqa: F405
|
|||||||
This function bypasses the UI workflow engine, so other layouts will not know
|
This function bypasses the UI workflow engine, so other layouts will not know
|
||||||
that something was drawn over them. In particular, if no other Layout is shown
|
that something was drawn over them. In particular, if no other Layout is shown
|
||||||
in a workflow, the homescreen will not redraw when the workflow is finished.
|
in a workflow, the homescreen will not redraw when the workflow is finished.
|
||||||
Use `workflow.kill_default()` if you need to avoid this situation.
|
Make sure you use `workflow.close_others()` before invoking this function
|
||||||
|
(note that `workflow.close_others()` is implicitly called with `button_request()`).
|
||||||
"""
|
"""
|
||||||
backlight_fade(style.BACKLIGHT_DIM)
|
backlight_fade(style.BACKLIGHT_DIM)
|
||||||
display.clear()
|
display.clear()
|
||||||
|
@ -3,7 +3,7 @@ import utime
|
|||||||
from trezor import log, loop
|
from trezor import log, loop
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
from typing import Any, Callable, Dict, Optional, Set
|
from typing import Callable, Dict, Optional, Set
|
||||||
|
|
||||||
IdleCallback = Callable[[], None]
|
IdleCallback = Callable[[], None]
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ tasks = set() # type: Set[loop.spawn]
|
|||||||
|
|
||||||
# Default workflow task, if a default workflow is running. Default workflow
|
# Default workflow task, if a default workflow is running. Default workflow
|
||||||
# is not contained in the `tasks` set above.
|
# is not contained in the `tasks` set above.
|
||||||
default_task = None # type: Optional[loop.Task]
|
default_task = None # type: Optional[loop.spawn]
|
||||||
|
|
||||||
# Constructor for the default workflow. Returns a workflow task.
|
# Constructor for the default workflow. Returns a workflow task.
|
||||||
default_constructor = None # type: Optional[Callable[[], loop.Task]]
|
default_constructor = None # type: Optional[Callable[[], loop.Task]]
|
||||||
@ -78,12 +78,10 @@ def start_default() -> None:
|
|||||||
assert default_constructor is not None
|
assert default_constructor is not None
|
||||||
|
|
||||||
if not default_task:
|
if not default_task:
|
||||||
default_task = default_constructor()
|
default_task = loop.spawn(default_constructor())
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.debug(__name__, "start default: %s", default_task)
|
log.debug(__name__, "start default: %s", default_task.task)
|
||||||
# Schedule the default task. Because the task can complete on its own,
|
default_task.set_finalizer(_finalize_default)
|
||||||
# we need to reset the `default_task` global in a finalizer.
|
|
||||||
loop.schedule(default_task, None, None, _finalize_default)
|
|
||||||
else:
|
else:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.debug(__name__, "default already started")
|
log.debug(__name__, "default already started")
|
||||||
@ -110,17 +108,19 @@ def kill_default() -> None:
|
|||||||
if __debug__:
|
if __debug__:
|
||||||
log.debug(__name__, "close default")
|
log.debug(__name__, "close default")
|
||||||
# We let the `_finalize_default` reset the global.
|
# We let the `_finalize_default` reset the global.
|
||||||
loop.close(default_task)
|
default_task.close()
|
||||||
|
|
||||||
|
|
||||||
def close_others() -> None:
|
def close_others() -> None:
|
||||||
"""Shut down all running tasks, except the one that is currently executing, and
|
"""Request workflow (and UI) exclusivity: shut down all running tasks, except
|
||||||
restart the default."""
|
the one that is currently executing.
|
||||||
try:
|
|
||||||
kill_default()
|
If this is called from outside a registered workflow, it is equivalent to "close
|
||||||
|
all tasks". In that case, the default task will be restarted afterwards.
|
||||||
|
"""
|
||||||
|
if default_task is not None and not default_task.is_running():
|
||||||
|
default_task.close()
|
||||||
# if no other tasks are running, start_default will run immediately
|
# if no other tasks are running, start_default will run immediately
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# we need a local copy of tasks because processing task.close() modifies
|
# we need a local copy of tasks because processing task.close() modifies
|
||||||
# the global instance
|
# the global instance
|
||||||
@ -131,39 +131,23 @@ def close_others() -> None:
|
|||||||
# if tasks were running, closing the last of them will run start_default
|
# if tasks were running, closing the last of them will run start_default
|
||||||
|
|
||||||
|
|
||||||
def _finalize_default(task: loop.Task, value: Any) -> None:
|
def _finalize_default(task: loop.spawn) -> None:
|
||||||
"""Finalizer for the default task. Cleans up globals and restarts the default
|
"""Finalizer for the default task. Cleans up globals and restarts the default
|
||||||
in case no other task is running."""
|
in case no other task is running."""
|
||||||
global default_task
|
global default_task
|
||||||
|
|
||||||
if default_task is task:
|
assert default_task is task # finalizer is closing something other than default?
|
||||||
|
assert default_constructor is not None # it should always be configured
|
||||||
|
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.debug(__name__, "default closed: %s", task)
|
log.debug(__name__, "default closed: %s", task.task)
|
||||||
default_task = None
|
default_task = None
|
||||||
|
|
||||||
if not tasks:
|
if not tasks:
|
||||||
# No registered workflows are running and we are in the default task
|
# No registered workflows are running and we are in the default task
|
||||||
# finalizer, so when this function finished, nothing will be running.
|
# finalizer, so when this function finished, nothing will be running.
|
||||||
# We must schedule a new instance of the default now.
|
# We must schedule a new instance of the default now.
|
||||||
if default_constructor is not None:
|
|
||||||
start_default()
|
start_default()
|
||||||
else:
|
|
||||||
raise RuntimeError # no tasks and no default constructor
|
|
||||||
|
|
||||||
else:
|
|
||||||
if __debug__:
|
|
||||||
log.warning(
|
|
||||||
__name__,
|
|
||||||
"default task does not match: task=%s, default_task=%s",
|
|
||||||
task,
|
|
||||||
default_task,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
# If required, a function `shutdown_default` should be written, that clears the
|
|
||||||
# default constructor and shuts down the running default task.
|
|
||||||
# We currently do not need such function, so I'm just noting how it should work.
|
|
||||||
|
|
||||||
|
|
||||||
class IdleTimer:
|
class IdleTimer:
|
||||||
|
Loading…
Reference in New Issue
Block a user