Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pagination for sign/verify message #1384

Merged
merged 10 commits into from Jan 11, 2021
Merged

Pagination for sign/verify message #1384

merged 10 commits into from Jan 11, 2021

Conversation

matejcik
Copy link
Contributor

@matejcik matejcik commented Dec 14, 2020

based on and supersedes #1337

The biggest part of this PR is actually a refactor of the render_text function, which adds three new outward-facing features:

  • the Span class can be used to count lines in a string
  • breaking lines on whitespace (enabled by default)
  • rendering embedded newlines

Includes @mmilata's patch to modtrezordisplay that allows rendering substrings, and takes advantage of this in render_text to avoid slicing passed-in strings. This causes rather solid savings in memory allocations: 114k allocs in text.py vs master's ~147k (i don't have a link to an artifact with this :( )
notably, there are zero allocations in calling render_text


the newlines rendering means that we can use the following going forward
old:

text.normal("Do you really", "want to change", "your PIN?")

new:

text.normal("Do you really\nwant to change\nyour PIN?")

which is an important step in #1005

Copy link
Member

@mmilata mmilata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! Your render_text is much more readable. UI diff looks legit.

core/src/apps/management/apply_settings.py Outdated Show resolved Hide resolved
core/src/apps/common/layout.py Show resolved Hide resolved
core/src/trezor/ui/text.py Outdated Show resolved Hide resolved
tests/device_tests/test_msg_signmessage.py Outdated Show resolved Hide resolved
@matejcik
Copy link
Contributor Author

added some unit tests in c2e73a1

changed behavior slightly in 49b55b5, this will introduce UI diffs that i won't be fixing at the moment. Feel free to ignore that commit until I update the UI fixtures, or review the diffs and push the necessary changes here if you like.

@mmilata
Copy link
Member

mmilata commented Dec 16, 2020

The diffs are OK, pushed fixtures in eebefff.

@matejcik matejcik marked this pull request as ready for review December 22, 2020 10:29
@matejcik matejcik requested review from mmilata and removed request for onvej-sl December 22, 2020 10:30
@matejcik
Copy link
Contributor Author

this is now ready for review, modulo passing CI checks.

@prusnak you're tagged for reviewing the C rendering code changes

for @mmilata:
the last collection of commits add more unit tests and some docs for Span, plus two API functions that are used in the updated paginate_text function. It is now more readable and more reliable, and also fixes some corner cases (trailing newlines) that were difficult to express properly before.

I implemented the "mock out ui.display" way of unit-testing, the final version is as clean as I believe possible for doing this particular sort of thing :)

There is also a proper UI test for the paginated signmessages

@matejcik
Copy link
Contributor Author

UI diff

Copy link
Member

@mmilata mmilata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!!! Left some comments inline.

Went through the UI diff, the changes are either barely perceptible or a clear improvement to the previous state.

core/src/trezor/ui/text.py Show resolved Hide resolved
def next_line(self) -> bool:
"""Advance the span to point to contents of the next line.

Returns True if the rendered should make newline afterwards, False if this is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo - rendered?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a83f110

the first character of the indicated item which should be considered.
The purpose is to allow rendering different "pages" of text, using the same `items`
argument (slicing the list could be expensive in terms of memory).
The item selected by `item_offset` must be a string.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: paginate_lines violates this statement (item_offset is font) though I don't think it poses a problem, maybe just remove the sentence?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of a problem actually, it reveals a bug: font instructions that precede item_offset are going to be ignored.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 02ca00d

if isinstance(word, int):
if word is BR or word is BR_HALF:
if isinstance(item, int):
if item is BR or item is BR_HALF:
# line break or half-line break
if offset_y > offset_y_max:
ui.display.text(offset_x, offset_y, "...", ui.BOLD, ui.GREY, bg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also be conditional on render_page_overflow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in a83f110

message_read = ""
message += "End."

def input_flow():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope for this PR but I'm wondering how to generalize this for other tests to use. Would be nice to record fixtures for all the pageable screens in tests that have them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, we'd need a debuglink indication that a screen is paginated, and ideally a page position as well.

relatively easy to implement, but i'm thinking maybe the redesign of ButtonRequests will solve this too?

@tsusanka tsusanka removed their request for review January 6, 2021 12:08
matejcik added a commit that referenced this pull request Jan 11, 2021
@matejcik
Copy link
Contributor Author

rebased on master, added changelogs.

ping @prusnak for C review, otherwise ready to merge

Copy link
Member

@prusnak prusnak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use const char * instead of char * to indicate we are not modifying the contents of the string, just slicing it.

core/embed/extmod/modtrezorui/display.c Outdated Show resolved Hide resolved
core/embed/extmod/modtrezorui/display.h Outdated Show resolved Hide resolved
core/embed/extmod/modtrezorui/modtrezorui-display.h Outdated Show resolved Hide resolved
core/embed/extmod/modtrezorui/modtrezorui-display.h Outdated Show resolved Hide resolved
@mmilata
Copy link
Member

mmilata commented Jan 11, 2021

Feel free to cherry-pick 1c9e247 with the suggested changes.

@matejcik
Copy link
Contributor Author

cherry-pick applied

@matejcik matejcik merged commit 58708cd into master Jan 11, 2021
@matejcik matejcik deleted the matejcik/pagination branch January 11, 2021 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants