mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 21:22:10 +00:00
feat(core/ui): unify progress.py code between models, implement storage translations
fixes #3520
This commit is contained in:
parent
0553a2d4b4
commit
de2fe3d6d6
1
core/.changelog.d/3520.fixed
Normal file
1
core/.changelog.d/3520.fixed
Normal file
@ -0,0 +1 @@
|
||||
Translate also texts for PIN progress loaders.
|
@ -538,6 +538,10 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_sign_message__verify_address;
|
||||
MP_QSTR_skip_first_paint;
|
||||
MP_QSTR_spending_amount;
|
||||
MP_QSTR_storage_msg__processing;
|
||||
MP_QSTR_storage_msg__starting;
|
||||
MP_QSTR_storage_msg__verifying_pin;
|
||||
MP_QSTR_storage_msg__wrong_pin;
|
||||
MP_QSTR_subprompt;
|
||||
MP_QSTR_subtitle;
|
||||
MP_QSTR_text_mono;
|
||||
|
@ -1234,6 +1234,10 @@ pub enum TranslatedString {
|
||||
ethereum__staking_unstake = 840, // "UNSTAKE"
|
||||
#[cfg(feature = "universal_fw")]
|
||||
ethereum__staking_unstake_intro = 841, // "Unstake ETH from Everstake?"
|
||||
storage_msg__processing = 842, // "PROCESSING"
|
||||
storage_msg__starting = 843, // "STARTING UP"
|
||||
storage_msg__verifying_pin = 844, // "VERIFYING PIN"
|
||||
storage_msg__wrong_pin = 845, // "WRONG PIN"
|
||||
}
|
||||
|
||||
impl TranslatedString {
|
||||
@ -2463,6 +2467,10 @@ impl TranslatedString {
|
||||
Self::ethereum__staking_unstake => "UNSTAKE",
|
||||
#[cfg(feature = "universal_fw")]
|
||||
Self::ethereum__staking_unstake_intro => "Unstake ETH from Everstake?",
|
||||
Self::storage_msg__processing => "PROCESSING",
|
||||
Self::storage_msg__starting => "STARTING UP",
|
||||
Self::storage_msg__verifying_pin => "VERIFYING PIN",
|
||||
Self::storage_msg__wrong_pin => "WRONG PIN",
|
||||
}
|
||||
}
|
||||
|
||||
@ -3693,6 +3701,10 @@ impl TranslatedString {
|
||||
Qstr::MP_QSTR_ethereum__staking_unstake => Some(Self::ethereum__staking_unstake),
|
||||
#[cfg(feature = "universal_fw")]
|
||||
Qstr::MP_QSTR_ethereum__staking_unstake_intro => Some(Self::ethereum__staking_unstake_intro),
|
||||
Qstr::MP_QSTR_storage_msg__processing => Some(Self::storage_msg__processing),
|
||||
Qstr::MP_QSTR_storage_msg__starting => Some(Self::storage_msg__starting),
|
||||
Qstr::MP_QSTR_storage_msg__verifying_pin => Some(Self::storage_msg__verifying_pin),
|
||||
Qstr::MP_QSTR_storage_msg__wrong_pin => Some(Self::storage_msg__wrong_pin),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1571,18 +1571,22 @@ extern "C" fn new_show_group_share_success(
|
||||
|
||||
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
|
||||
let description: StrBuffer =
|
||||
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
|
||||
let title: Option<StrBuffer> = kwargs
|
||||
.get(Qstr::MP_QSTR_title)
|
||||
.and_then(Obj::try_into_option)
|
||||
.unwrap_or(None);
|
||||
|
||||
let mut progress =
|
||||
Progress::new(indeterminate, description).with_update_description(StrBuffer::alloc);
|
||||
if let Some(title) = title {
|
||||
progress = progress.with_title(title);
|
||||
};
|
||||
|
||||
// Description updates are received as &str and we need to provide a way to
|
||||
// convert them to StrBuffer.
|
||||
let obj = LayoutObj::new(
|
||||
Progress::new(indeterminate, description)
|
||||
.with_title(title)
|
||||
.with_update_description(StrBuffer::alloc),
|
||||
)?;
|
||||
let obj = LayoutObj::new(progress)?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
@ -2074,9 +2078,9 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
|
||||
/// def show_progress(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// description: str,
|
||||
/// indeterminate: bool = False,
|
||||
/// description: str = "",
|
||||
/// title: str | None = None,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Show progress loader. Please note that the number of lines reserved on screen for
|
||||
/// description is determined at construction time. If you want multiline descriptions
|
||||
|
@ -1547,10 +1547,18 @@ extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs:
|
||||
|
||||
extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let indeterminate: bool = kwargs.get_or(Qstr::MP_QSTR_indeterminate, false)?;
|
||||
let description: StrBuffer =
|
||||
kwargs.get_or(Qstr::MP_QSTR_description, StrBuffer::empty())?;
|
||||
let title: Option<StrBuffer> = kwargs
|
||||
.get(Qstr::MP_QSTR_title)
|
||||
.and_then(Obj::try_into_option)
|
||||
.unwrap_or(None);
|
||||
|
||||
let (title, description) = if let Some(title) = title {
|
||||
(title, description)
|
||||
} else {
|
||||
(description, StrBuffer::empty())
|
||||
};
|
||||
|
||||
// Description updates are received as &str and we need to provide a way to
|
||||
// convert them to StrBuffer.
|
||||
@ -2130,9 +2138,9 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
|
||||
/// def show_progress(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// description: str,
|
||||
/// indeterminate: bool = False,
|
||||
/// description: str = "",
|
||||
/// title: str | None = None,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Show progress loader. Please note that the number of lines reserved on screen for
|
||||
/// description is determined at construction time. If you want multiline descriptions
|
||||
|
@ -399,9 +399,9 @@ def show_group_share_success(
|
||||
# rust/src/ui/model_tr/layout.rs
|
||||
def show_progress(
|
||||
*,
|
||||
title: str,
|
||||
description: str,
|
||||
indeterminate: bool = False,
|
||||
description: str = "",
|
||||
title: str | None = None,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Show progress loader. Please note that the number of lines reserved on screen for
|
||||
description is determined at construction time. If you want multiline descriptions
|
||||
@ -917,9 +917,9 @@ def show_remaining_shares(
|
||||
# rust/src/ui/model_tt/layout.rs
|
||||
def show_progress(
|
||||
*,
|
||||
title: str,
|
||||
description: str,
|
||||
indeterminate: bool = False,
|
||||
description: str = "",
|
||||
title: str | None = None,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Show progress loader. Please note that the number of lines reserved on screen for
|
||||
description is determined at construction time. If you want multiline descriptions
|
||||
|
@ -756,6 +756,10 @@ class TR:
|
||||
stellar__value_sha256: str = "Value (SHA-256):"
|
||||
stellar__wanna_clean_value_key_template: str = "Do you want to clear value key {0}?"
|
||||
stellar__your_account: str = " your account"
|
||||
storage_msg__processing: str = "PROCESSING"
|
||||
storage_msg__starting: str = "STARTING UP"
|
||||
storage_msg__verifying_pin: str = "VERIFYING PIN"
|
||||
storage_msg__wrong_pin: str = "WRONG PIN"
|
||||
tezos__baker_address: str = "Baker address:"
|
||||
tezos__balance: str = "Balance:"
|
||||
tezos__ballot: str = "Ballot:"
|
||||
|
4
core/src/all_modules.py
generated
4
core/src/all_modules.py
generated
@ -169,8 +169,6 @@ trezor.ui.layouts.tr.fido
|
||||
import trezor.ui.layouts.tr.fido
|
||||
trezor.ui.layouts.tr.homescreen
|
||||
import trezor.ui.layouts.tr.homescreen
|
||||
trezor.ui.layouts.tr.progress
|
||||
import trezor.ui.layouts.tr.progress
|
||||
trezor.ui.layouts.tr.recovery
|
||||
import trezor.ui.layouts.tr.recovery
|
||||
trezor.ui.layouts.tr.reset
|
||||
@ -181,8 +179,6 @@ trezor.ui.layouts.tt.fido
|
||||
import trezor.ui.layouts.tt.fido
|
||||
trezor.ui.layouts.tt.homescreen
|
||||
import trezor.ui.layouts.tt.homescreen
|
||||
trezor.ui.layouts.tt.progress
|
||||
import trezor.ui.layouts.tt.progress
|
||||
trezor.ui.layouts.tt.recovery
|
||||
import trezor.ui.layouts.tt.recovery
|
||||
trezor.ui.layouts.tt.reset
|
||||
|
@ -34,7 +34,7 @@ async def authenticate_device(msg: AuthenticateDevice) -> AuthenticityProof:
|
||||
write_compact_size(h, len(msg.challenge))
|
||||
h.extend(msg.challenge)
|
||||
|
||||
spinner = progress("", description=TR.progress__authenticity_check)
|
||||
spinner = progress(TR.progress__authenticity_check)
|
||||
spinner.report(0)
|
||||
|
||||
try:
|
||||
|
@ -24,7 +24,7 @@ async def change_language(msg: ChangeLanguage) -> Success:
|
||||
nonlocal loader
|
||||
if loader is None:
|
||||
workflow.close_others()
|
||||
loader = progress("", TR.language__progress)
|
||||
loader = progress(TR.language__progress)
|
||||
loader.report(value)
|
||||
|
||||
if msg.data_length == 0:
|
||||
|
@ -44,7 +44,7 @@ async def reset_device(msg: ResetDevice) -> Success:
|
||||
await confirm_reset_device(title)
|
||||
|
||||
# Rendering empty loader so users do not feel a freezing screen
|
||||
render_empty_loader(TR.progress__processing, "")
|
||||
render_empty_loader(config.StorageMessage.PROCESSING_MSG)
|
||||
|
||||
# wipe storage to make sure the device is in a clear state
|
||||
storage.reset()
|
||||
|
@ -1,7 +1,9 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from . import config
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
from typing import Any, Container
|
||||
|
||||
from trezor.ui.layouts.common import ProgressLayout
|
||||
|
||||
@ -11,13 +13,15 @@ _progress_layout: ProgressLayout | None = None
|
||||
_started_with_empty_loader = False
|
||||
keepalive_callback: Any = None
|
||||
|
||||
_ignore_loader_messages: tuple[str, ...] = ()
|
||||
_ignore_loader_messages: Container[config.StorageMessage] = ()
|
||||
|
||||
|
||||
def ignore_nonpin_loader_messages() -> None:
|
||||
global _ignore_loader_messages
|
||||
# TODO: handle translation of those (in C)
|
||||
_ignore_loader_messages = ("Processing", "Starting up")
|
||||
_ignore_loader_messages = (
|
||||
config.StorageMessage.PROCESSING_MSG,
|
||||
config.StorageMessage.STARTING_MSG,
|
||||
)
|
||||
|
||||
|
||||
def allow_all_loader_messages() -> None:
|
||||
@ -25,7 +29,7 @@ def allow_all_loader_messages() -> None:
|
||||
_ignore_loader_messages = ()
|
||||
|
||||
|
||||
def render_empty_loader(message: str, description: str) -> None:
|
||||
def render_empty_loader(message: config.StorageMessage, description: str = "") -> None:
|
||||
"""Render empty loader to prevent the screen appear to be frozen."""
|
||||
from trezor.ui.layouts.progress import pin_progress
|
||||
|
||||
@ -38,7 +42,9 @@ def render_empty_loader(message: str, description: str) -> None:
|
||||
_started_with_empty_loader = True
|
||||
|
||||
|
||||
def show_pin_timeout(seconds: int, progress: int, message: str) -> bool:
|
||||
def show_pin_timeout(
|
||||
seconds: int, progress: int, message: config.StorageMessage
|
||||
) -> bool:
|
||||
from trezor import TR
|
||||
from trezor.ui.layouts.progress import pin_progress
|
||||
|
||||
|
@ -1,6 +1,100 @@
|
||||
from trezor import utils
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if utils.UI_LAYOUT == "TT":
|
||||
from .tt.progress import * # noqa: F401,F403
|
||||
elif utils.UI_LAYOUT == "TR":
|
||||
from .tr.progress import * # noqa: F401,F403
|
||||
import trezorui2
|
||||
from trezor import TR, config, ui, utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from .common import ProgressLayout
|
||||
|
||||
|
||||
def _storage_message_to_str(message: config.StorageMessage | None) -> str | None:
|
||||
from trezor import TR
|
||||
|
||||
if message is None:
|
||||
return None
|
||||
|
||||
if message == config.StorageMessage.NO_MSG:
|
||||
return ""
|
||||
if message == config.StorageMessage.VERIFYING_PIN_MSG:
|
||||
return TR.storage_msg__verifying_pin
|
||||
if message == config.StorageMessage.PROCESSING_MSG:
|
||||
return TR.storage_msg__processing
|
||||
if message == config.StorageMessage.STARTING_MSG:
|
||||
return TR.storage_msg__starting
|
||||
if message == config.StorageMessage.WRONG_PIN_MSG:
|
||||
return TR.storage_msg__wrong_pin
|
||||
raise RuntimeError # unknown message
|
||||
|
||||
|
||||
class RustProgress:
|
||||
def __init__(
|
||||
self,
|
||||
layout: Any,
|
||||
):
|
||||
self.layout = layout
|
||||
ui.backlight_fade(ui.style.BACKLIGHT_DIM)
|
||||
self.layout.attach_timer_fn(self.set_timer)
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL)
|
||||
|
||||
def set_timer(self, token: int, deadline: int) -> None:
|
||||
raise RuntimeError # progress layouts should not set timers
|
||||
|
||||
def report(self, value: int, description: str | None = None):
|
||||
msg = self.layout.progress_event(value, description or "")
|
||||
assert msg is None
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
|
||||
|
||||
def progress(
|
||||
description: str | None = None,
|
||||
title: str | None = None,
|
||||
indeterminate: bool = False,
|
||||
) -> ProgressLayout:
|
||||
if description is None:
|
||||
description = TR.progress__please_wait # def_arg
|
||||
|
||||
if title is not None:
|
||||
title = title.upper()
|
||||
elif not utils.MODEL_IS_T2B1:
|
||||
# on TT, uppercase the description which ends up on top of the screen
|
||||
# when no title is set
|
||||
description = description.upper()
|
||||
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress(
|
||||
description=description,
|
||||
title=title,
|
||||
indeterminate=indeterminate,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def bitcoin_progress(message: str) -> ProgressLayout:
|
||||
return progress(message)
|
||||
|
||||
|
||||
def coinjoin_progress(message: str) -> ProgressLayout:
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
|
||||
)
|
||||
|
||||
|
||||
def pin_progress(title: config.StorageMessage, description: str) -> ProgressLayout:
|
||||
return progress(description=description, title=_storage_message_to_str(title))
|
||||
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
|
||||
def monero_keyimage_sync_progress() -> ProgressLayout:
|
||||
return progress(TR.progress__syncing)
|
||||
|
||||
def monero_live_refresh_progress() -> ProgressLayout:
|
||||
return progress(TR.progress__refreshing, indeterminate=True)
|
||||
|
||||
def monero_transaction_progress_inner() -> ProgressLayout:
|
||||
return progress(TR.progress__signing_transaction)
|
||||
|
@ -1,69 +0,0 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import trezorui2
|
||||
from trezor import TR, ui, utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from ..common import ProgressLayout
|
||||
|
||||
|
||||
class RustProgress:
|
||||
def __init__(
|
||||
self,
|
||||
layout: Any,
|
||||
):
|
||||
self.layout = layout
|
||||
self.layout.attach_timer_fn(self.set_timer)
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
|
||||
def set_timer(self, token: int, deadline: int) -> None:
|
||||
raise RuntimeError # progress layouts should not set timers
|
||||
|
||||
def report(self, value: int, description: str | None = None):
|
||||
msg = self.layout.progress_event(value, description or "")
|
||||
assert msg is None
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
|
||||
|
||||
def progress(
|
||||
message: str | None = None,
|
||||
description: str | None = None,
|
||||
indeterminate: bool = False,
|
||||
) -> ProgressLayout:
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress(
|
||||
title=message.upper() if message else "",
|
||||
indeterminate=indeterminate,
|
||||
description=description or "",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def bitcoin_progress(description: str) -> ProgressLayout:
|
||||
return progress("", description)
|
||||
|
||||
|
||||
def coinjoin_progress(message: str) -> ProgressLayout:
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
|
||||
)
|
||||
|
||||
|
||||
def pin_progress(message: str, description: str) -> ProgressLayout:
|
||||
return progress(message, description)
|
||||
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
|
||||
def monero_keyimage_sync_progress() -> ProgressLayout:
|
||||
return progress("", TR.progress__syncing)
|
||||
|
||||
def monero_live_refresh_progress() -> ProgressLayout:
|
||||
return progress("", TR.progress__refreshing, indeterminate=True)
|
||||
|
||||
def monero_transaction_progress_inner() -> ProgressLayout:
|
||||
return progress("", TR.progress__signing_transaction)
|
@ -1,72 +0,0 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import trezorui2
|
||||
from trezor import TR, ui, utils
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
from ..common import ProgressLayout
|
||||
|
||||
|
||||
class RustProgress:
|
||||
def __init__(
|
||||
self,
|
||||
layout: Any,
|
||||
):
|
||||
self.layout = layout
|
||||
ui.backlight_fade(ui.style.BACKLIGHT_DIM)
|
||||
self.layout.attach_timer_fn(self.set_timer)
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
ui.backlight_fade(ui.style.BACKLIGHT_NORMAL)
|
||||
|
||||
def set_timer(self, token: int, deadline: int) -> None:
|
||||
raise RuntimeError # progress layouts should not set timers
|
||||
|
||||
def report(self, value: int, description: str | None = None):
|
||||
msg = self.layout.progress_event(value, description or "")
|
||||
assert msg is None
|
||||
self.layout.paint()
|
||||
ui.refresh()
|
||||
|
||||
|
||||
def progress(
|
||||
message: str | None = None,
|
||||
description: str | None = None,
|
||||
indeterminate: bool = False,
|
||||
) -> ProgressLayout:
|
||||
message = message or TR.progress__please_wait # def_arg
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress(
|
||||
title=message.upper(),
|
||||
indeterminate=indeterminate,
|
||||
description=description or "",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def bitcoin_progress(message: str) -> ProgressLayout:
|
||||
return progress(message)
|
||||
|
||||
|
||||
def coinjoin_progress(message: str) -> ProgressLayout:
|
||||
return RustProgress(
|
||||
layout=trezorui2.show_progress_coinjoin(title=message, indeterminate=False)
|
||||
)
|
||||
|
||||
|
||||
def pin_progress(message: str, description: str) -> ProgressLayout:
|
||||
return progress(message, description=description)
|
||||
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
|
||||
def monero_keyimage_sync_progress() -> ProgressLayout:
|
||||
return progress("", TR.progress__syncing)
|
||||
|
||||
def monero_live_refresh_progress() -> ProgressLayout:
|
||||
return progress("", TR.progress__refreshing, indeterminate=True)
|
||||
|
||||
def monero_transaction_progress_inner() -> ProgressLayout:
|
||||
return progress("", TR.progress__signing_transaction)
|
@ -677,6 +677,10 @@
|
||||
"sign_message__confirm_message": "CONFIRM MESSAGE",
|
||||
"sign_message__message_size": "Message size:",
|
||||
"sign_message__verify_address": "VERIFY ADDRESS",
|
||||
"storage_msg__verifying_pin": "VERIFYING PIN",
|
||||
"storage_msg__processing": "PROCESSING",
|
||||
"storage_msg__starting": "STARTING UP",
|
||||
"storage_msg__wrong_pin": "WRONG PIN",
|
||||
"solana__account_index": "Account index",
|
||||
"solana__associated_token_account": "Associated token account",
|
||||
"solana__confirm_multisig": "Confirm multisig",
|
||||
|
@ -840,5 +840,9 @@
|
||||
"838": "ethereum__staking_stake_address",
|
||||
"839": "ethereum__staking_stake_intro",
|
||||
"840": "ethereum__staking_unstake",
|
||||
"841": "ethereum__staking_unstake_intro"
|
||||
"841": "ethereum__staking_unstake_intro",
|
||||
"842": "storage_msg__processing",
|
||||
"843": "storage_msg__starting",
|
||||
"844": "storage_msg__verifying_pin",
|
||||
"845": "storage_msg__wrong_pin"
|
||||
}
|
||||
|
@ -12196,7 +12196,7 @@
|
||||
"TR_en_test_cancel.py::test_cancel_message_via_initialize[message1]": "41b9fc37f230520f9d94df226ff8433822e56ea4276a31ef99171a774e477045",
|
||||
"TR_en_test_cancel.py::test_cancel_on_paginated": "79f025ebfbdc5a81dae1385b17d2d802280063479c8480fa5281734fe1542385",
|
||||
"TR_en_test_debuglink.py::test_softlock_instability": "cff029b728b242ec07f405a0fcd12a77212f0a28e9ec14f1b9e2db1b63293783",
|
||||
"TR_en_test_firmware_hash.py::test_firmware_hash_emu": "a5099e7016da59ba2a1efac6a060711383f199d674c8357146738c42b79be6ff",
|
||||
"TR_en_test_firmware_hash.py::test_firmware_hash_emu": "a020914cfcb0f51772fc14300eb89899b605e114cb75655874aed44ef29695c0",
|
||||
"TR_en_test_firmware_hash.py::test_firmware_hash_hw": "8c801bd0142e5c1ad4aad50b34c7debb1b8f17a2e0a87eb7f95531b9fd15e095",
|
||||
"TR_en_test_language.py::test_error_invalid_data_hash": "0cb01b8002472dff316d6eb3ba901dffb762d88fdf61e5ef8642ca7772d3e71c",
|
||||
"TR_en_test_language.py::test_error_invalid_data_length": "4ffbed72e7ed7fbab85f830952200adf7758af81b658b56de4672344120456a6",
|
||||
@ -19514,28 +19514,28 @@
|
||||
"TT_en_test_debuglink.py::test_softlock_instability": "55cb4cbeec68bd8ccee460034677cf8053f8f688d5c3559f360c38a205b34e37",
|
||||
"TT_en_test_firmware_hash.py::test_firmware_hash_emu": "2a63f0bd10ba99e223f571482d4af635653bb8a3bddc1d8400777ee5519bc605",
|
||||
"TT_en_test_firmware_hash.py::test_firmware_hash_hw": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
|
||||
"TT_en_test_language.py::test_error_invalid_data_hash": "67782b952469c260afac92bac1efc2ba9c2f342319ae95fb5e91c843da2a6e46",
|
||||
"TT_en_test_language.py::test_error_invalid_data_hash": "aaf31bdc64a531bc9084a003b2ad78a9fb91ba9b138090b1e2daf78ca4c106f9",
|
||||
"TT_en_test_language.py::test_error_invalid_data_length": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
|
||||
"TT_en_test_language.py::test_error_invalid_header_magic": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
|
||||
"TT_en_test_language.py::test_error_invalid_signature": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
|
||||
"TT_en_test_language.py::test_error_too_long": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
|
||||
"TT_en_test_language.py::test_error_version_mismatch": "d702b0f90581cf17e0f77b4d318324a002deec42c2c5cb8860d51f6cb50f5739",
|
||||
"TT_en_test_language.py::test_full_language_change[cs]": "1cf02eca93e97af9c4a4193a04050f43ddc7c627cca85dc7486050977d89d95b",
|
||||
"TT_en_test_language.py::test_full_language_change[de]": "d05c45a698f9e8a00b7f64bee10077dbce8e592fb5f76b76ba37e62df8d34e6c",
|
||||
"TT_en_test_language.py::test_full_language_change[cs]": "82f805dacbd77f3fe46224744a2c2fe24623a2a32aa3b538ffc15ea147c26c61",
|
||||
"TT_en_test_language.py::test_full_language_change[de]": "637494aacf526b8c6465a5c48a35eee4fa71d90d9f90d7c675c555bc5df75442",
|
||||
"TT_en_test_language.py::test_full_language_change[en]": "5f6cec419aad5e5658f6fda45c2cd40fa4581823e7f9f0c4199970cd179bfd4e",
|
||||
"TT_en_test_language.py::test_full_language_change[es]": "fcb472f8786ab55cc7b90450a002165fd74ed88edc0d41a0dffd741b801d7f0b",
|
||||
"TT_en_test_language.py::test_full_language_change[fr]": "a6b00695cb76f4fcc7197d37df49c3b1997da6ed23f2c21330d30e0f28dc910d",
|
||||
"TT_en_test_language.py::test_header_trailing_data": "be40adb967cdb6ed5857aebeabbd13c65900fc8c2aa30ff90e239b911fbd9c59",
|
||||
"TT_en_test_language.py::test_language_is_removed_after_wipe": "3e1fb6ae0bdcc7b306971d831c48e989d176cb57b10e69b319f546e0f5437f9c",
|
||||
"TT_en_test_language.py::test_full_language_change[es]": "6c3c6983dedaf60e8818c0acdff7f1ba83ff9106333d834b8bed02d910bf5b1f",
|
||||
"TT_en_test_language.py::test_full_language_change[fr]": "7e1f16d84163fa6b8a8acce859f5c5e97ded578c28f75629e4f9bd587cd051a8",
|
||||
"TT_en_test_language.py::test_header_trailing_data": "073921ad154051d3ae330aa981a7c8ddf725006ffd007a9f131cdec0ccb82097",
|
||||
"TT_en_test_language.py::test_language_is_removed_after_wipe": "094c2025512f5e4b32344313a4c3d9a1e62d8b1e04eee4dbc282509082d76979",
|
||||
"TT_en_test_language.py::test_reject_update": "78b8f16e00c5d653a7d5c0929d21ae8ae1c76798fe28f0eb6edee8e2ee8b0202",
|
||||
"TT_en_test_language.py::test_silent_first_install[False-False]": "91184a50875388be3e29102184c2828150196f29cc59cb0e81fa6623d8ddb796",
|
||||
"TT_en_test_language.py::test_silent_first_install[None-False]": "91184a50875388be3e29102184c2828150196f29cc59cb0e81fa6623d8ddb796",
|
||||
"TT_en_test_language.py::test_silent_first_install[True-True]": "5620e376c365737f72b1b86d4942c162ef1f65ff159cb8262f2411e01fa0b016",
|
||||
"TT_en_test_language.py::test_switch_from_english[None]": "0f92d5c7b12c2ab21152dbc9a5498859990476f91267f337dfad4b35c87e5de2",
|
||||
"TT_en_test_language.py::test_switch_from_english[True]": "0f92d5c7b12c2ab21152dbc9a5498859990476f91267f337dfad4b35c87e5de2",
|
||||
"TT_en_test_language.py::test_silent_first_install[False-False]": "7476715631cb4348ca5bc8ecdac99792abfc77b10da654305e1d09ce5e838176",
|
||||
"TT_en_test_language.py::test_silent_first_install[None-False]": "7476715631cb4348ca5bc8ecdac99792abfc77b10da654305e1d09ce5e838176",
|
||||
"TT_en_test_language.py::test_silent_first_install[True-True]": "944168e4747abf8a2a894ed59aad65de2d0e7193488b22869e3f59be034f2e5f",
|
||||
"TT_en_test_language.py::test_switch_from_english[None]": "dc4fef22119297c57f6b239143880cdd8d9f08199ff596467ab17db1a64b015d",
|
||||
"TT_en_test_language.py::test_switch_from_english[True]": "dc4fef22119297c57f6b239143880cdd8d9f08199ff596467ab17db1a64b015d",
|
||||
"TT_en_test_language.py::test_switch_from_english_not_silent": "80a6e289138a604cf351a29511cf6f85e2243591317894703152787e1351a1a3",
|
||||
"TT_en_test_language.py::test_switch_language": "2d7cc1088467af2f13ec08755cd2d11e39b463209e92ef9a06d1eec0cfb8dde0",
|
||||
"TT_en_test_language.py::test_translations_renders_on_screen": "9e96d81519ee2405b37a18dd856209373366665d1d9921da5ea73edcf2a74e88",
|
||||
"TT_en_test_language.py::test_switch_language": "c6d3537688d4ad0169fa2e8d43d9d68f7965ac09e15e31eb618d4a40dfd9be5d",
|
||||
"TT_en_test_language.py::test_translations_renders_on_screen": "30c57160aa25242ac290960c65bfe9d2f0bd3ee74ca97809f33351900c3a8c5e",
|
||||
"TT_en_test_msg_applysettings.py::test_apply_homescreen_jpeg": "0e2a71ac60add6bebc03645b6f4f6f19abdba56f1e55e799479b116e5a66aef6",
|
||||
"TT_en_test_msg_applysettings.py::test_apply_homescreen_jpeg_progressive": "4d7c67024ee17436071e5cf2f79c36453249c95314a732580623cb1f1cdbfdf3",
|
||||
"TT_en_test_msg_applysettings.py::test_apply_homescreen_jpeg_wrong_size": "4d7c67024ee17436071e5cf2f79c36453249c95314a732580623cb1f1cdbfdf3",
|
||||
|
Loading…
Reference in New Issue
Block a user