From b06cfb32d0556f605777b13ecdf1e95d1edbd1cc Mon Sep 17 00:00:00 2001 From: grdddj Date: Thu, 30 Mar 2023 18:55:13 +0200 Subject: [PATCH] rust: add new trace methods --- core/embed/rust/src/trace.rs | 69 ++++++++++++++++--- .../rust/src/ui/component/text/paragraphs.rs | 2 + core/embed/rust/src/ui/layout/obj.rs | 49 +++++++++---- .../rust/src/ui/model_tt/component/frame.rs | 6 +- .../model_tt/component/keyboard/mnemonic.rs | 1 + .../model_tt/component/keyboard/passphrase.rs | 1 + .../src/ui/model_tt/component/keyboard/pin.rs | 11 +++ .../rust/src/ui/model_tt/component/page.rs | 24 +++---- 8 files changed, 125 insertions(+), 38 deletions(-) diff --git a/core/embed/rust/src/trace.rs b/core/embed/rust/src/trace.rs index 6af52b82c9..50baedf5ef 100644 --- a/core/embed/rust/src/trace.rs +++ b/core/embed/rust/src/trace.rs @@ -1,3 +1,5 @@ +use heapless::String; + /// Visitor passed into `Trace` types. pub trait Tracer { fn int(&mut self, i: i64); @@ -6,12 +8,25 @@ pub trait Tracer { fn symbol(&mut self, name: &str); fn open(&mut self, name: &str); fn field(&mut self, name: &str, value: &dyn Trace); + fn title(&mut self, title: &str); + fn button(&mut self, button: &str); + fn content_flag(&mut self); + fn kw_pair(&mut self, key: &str, value: &dyn Trace); fn close(&mut self); } +// Identifiers for tagging various parts of the Trace +// message - so that things like title or the main screen +// content can be read in debug mode by micropython. +pub const TITLE_TAG: &str = " **TITLE** "; +pub const BTN_TAG: &str = " **BTN** "; +pub const CONTENT_TAG: &str = " **CONTENT** "; +// For when the button is not used +pub const EMPTY_BTN: &str = "---"; + /// Value that can describe own structure and data using the `Tracer` interface. pub trait Trace { - fn trace(&self, d: &mut dyn Tracer); + fn trace(&self, t: &mut dyn Tracer); } impl Trace for &[u8] { @@ -26,6 +41,12 @@ impl Trace for &[u8; N] { } } +impl Trace for String { + fn trace(&self, t: &mut dyn Tracer) { + t.string(&self[..]) + } +} + impl Trace for &str { fn trace(&self, t: &mut dyn Tracer) { t.string(self); @@ -68,24 +89,54 @@ mod tests { } fn symbol(&mut self, name: &str) { - self.extend(name.as_bytes()) + self.string("<"); + self.string(name); + self.string(">"); } fn open(&mut self, name: &str) { - self.extend(b"<"); - self.extend(name.as_bytes()); - self.extend(b" "); + self.string("<"); + self.string(name); + self.string(" "); } fn field(&mut self, name: &str, value: &dyn Trace) { - self.extend(name.as_bytes()); - self.extend(b":"); + self.string(name); + self.string(":"); value.trace(self); - self.extend(b" "); + self.string(" "); + } + + /// Mark the string as a title/header. + fn title(&mut self, title: &str) { + self.string(TITLE_TAG); + self.string(title); + self.string(TITLE_TAG); + } + + /// Mark the string as a button content. + fn button(&mut self, button: &str) { + self.string(BTN_TAG); + self.string(button); + self.string(BTN_TAG); + } + + // Mark the following as content visible on the screen, + // until it is called next time. + fn content_flag(&mut self) { + self.string(CONTENT_TAG); + } + + /// Key-value pair for easy parsing + fn kw_pair(&mut self, key: &str, value: &dyn Trace) { + self.string(key); + self.string("::"); + value.trace(self); + self.string(","); // mostly for human readability } fn close(&mut self) { - self.extend(b">") + self.string(">") } } } diff --git a/core/embed/rust/src/ui/component/text/paragraphs.rs b/core/embed/rust/src/ui/component/text/paragraphs.rs index a906cf4e84..e66a5ae55c 100644 --- a/core/embed/rust/src/ui/component/text/paragraphs.rs +++ b/core/embed/rust/src/ui/component/text/paragraphs.rs @@ -239,6 +239,7 @@ pub mod trace { impl crate::trace::Trace for Paragraphs { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Paragraphs"); + t.content_flag(); Self::foreach_visible( &self.source, &self.visible, @@ -248,6 +249,7 @@ pub mod trace { t.string("\n"); }, ); + t.content_flag(); t.close(); } } diff --git a/core/embed/rust/src/ui/layout/obj.rs b/core/embed/rust/src/ui/layout/obj.rs index 4c7d2dc0c5..1447772222 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -231,30 +231,51 @@ impl LayoutObj { } fn symbol(&mut self, name: &str) { - self.0 - .call_with_n_args(&[ - "<".try_into().unwrap(), - name.try_into().unwrap(), - ">".try_into().unwrap(), - ]) - .unwrap(); + self.string("<"); + self.string(name); + self.string(">"); } fn open(&mut self, name: &str) { - self.0 - .call_with_n_args(&["<".try_into().unwrap(), name.try_into().unwrap()]) - .unwrap(); + self.string("<"); + self.string(name); + self.string(" "); } fn field(&mut self, name: &str, value: &dyn Trace) { - self.0 - .call_with_n_args(&[name.try_into().unwrap(), ": ".try_into().unwrap()]) - .unwrap(); + self.string(name); + self.string(":"); value.trace(self); + self.string(" "); + } + + /// Mark the string as a title/header. + fn title(&mut self, title: &str) { + self.string(crate::trace::TITLE_TAG); + self.string(title); + self.string(crate::trace::TITLE_TAG); + } + + /// Mark the string as a button content. + fn button(&mut self, button: &str) { + self.string(crate::trace::BTN_TAG); + self.string(button); + self.string(crate::trace::BTN_TAG); + } + + fn content_flag(&mut self) { + self.string(crate::trace::CONTENT_TAG); + } + + fn kw_pair(&mut self, key: &str, value: &dyn Trace) { + self.string(key); + self.string("::"); + value.trace(self); + self.string(","); // mostly for human readability } fn close(&mut self) { - self.0.call_with_n_args(&[">".try_into().unwrap()]).unwrap(); + self.string(">") } } diff --git a/core/embed/rust/src/ui/model_tt/component/frame.rs b/core/embed/rust/src/ui/model_tt/component/frame.rs index 9df7a7daaf..6cb9f7acd8 100644 --- a/core/embed/rust/src/ui/model_tt/component/frame.rs +++ b/core/embed/rust/src/ui/model_tt/component/frame.rs @@ -190,9 +190,9 @@ where { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Frame"); - t.field("title", &self.title); + t.title(self.title.inner().text().as_ref()); if let Some(s) = &self.subtitle { - t.field("subtitle", s); + t.title(s.inner().text().as_ref()); } if let Some(b) = &self.button { t.field("button", b); @@ -283,7 +283,7 @@ where { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("NotificationFrame"); - t.field("title", &self.title); + t.title(self.title.as_ref()); t.field("content", &self.content); t.close(); } diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs index 9b725b083d..9c398ee893 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs @@ -193,6 +193,7 @@ pub enum MnemonicInputMsg { #[cfg(feature = "ui_debug")] impl crate::trace::Trace for MnemonicKeyboard { fn trace(&self, t: &mut dyn crate::trace::Tracer) { + // TODO: could differentiate between BIP39 and SLIP39 t.open("MnemonicKeyboard"); t.close(); } diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs index dd68aff7de..60cb5ebe62 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/passphrase.rs @@ -378,6 +378,7 @@ impl Component for Input { impl crate::trace::Trace for PassphraseKeyboard { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("PassphraseKeyboard"); + t.kw_pair("textbox", &self.input.inner().textbox.content()); t.close(); } } diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs index 632856dcac..a1709e7e27 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/pin.rs @@ -469,6 +469,17 @@ where { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("PinKeyboard"); + // So that debuglink knows the locations of the buttons + let mut digits_order: String<10> = String::new(); + for btn in self.digit_btns.iter() { + let btn_content = btn.inner().content(); + if let ButtonContent::Text(text) = btn_content { + unwrap!(digits_order.push_str(text)); + } + } + t.kw_pair("digits_order", &digits_order); + // TODO: textbox does not get updated when the pin is changed + t.kw_pair("textbox", &self.textbox.inner().pin()); t.close(); } } diff --git a/core/embed/rust/src/ui/model_tt/component/page.rs b/core/embed/rust/src/ui/model_tt/component/page.rs index 37be687fb4..31e7b19e79 100644 --- a/core/embed/rust/src/ui/model_tt/component/page.rs +++ b/core/embed/rust/src/ui/model_tt/component/page.rs @@ -312,8 +312,8 @@ where { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("SwipePage"); - t.field("active_page", &self.scrollbar.active_page); - t.field("page_count", &self.scrollbar.page_count); + t.kw_pair("active_page", &self.scrollbar.active_page); + t.kw_pair("page_count", &self.scrollbar.page_count); t.field("content", &self.content); t.field("controls", &self.controls); t.close(); @@ -561,7 +561,7 @@ mod tests { page.place(SCREEN); let expected = - " controls: >"; + " buttons: >"; assert_eq!(trace(&page), expected); swipe_up(&mut page); @@ -588,7 +588,7 @@ mod tests { ); page.place(SCREEN); - let expected = " controls: >"; + let expected = " controls: >"; assert_eq!(trace(&page), expected); swipe_up(&mut page); @@ -611,8 +611,8 @@ mod tests { ); page.place(SCREEN); - let expected1 = " controls: > >"; - let expected2 = " controls: > >"; + let expected1 = " controls: > >"; + let expected2 = " controls: > >"; assert_eq!(trace(&page), expected1); swipe_down(&mut page); @@ -647,9 +647,9 @@ mod tests { ); page.place(SCREEN); - let expected1 = " controls: > >"; - let expected2 = " controls: > >"; - let expected3 = " controls: > >"; + let expected1 = " controls: > >"; + let expected2 = " controls: > >"; + let expected3 = " controls: > >"; assert_eq!(trace(&page), expected1); swipe_down(&mut page); @@ -681,9 +681,9 @@ mod tests { ); page.place(SCREEN); - let expected1 = " controls: > >"; - let expected2 = " controls: > >"; - let expected3 = " controls: > >"; + let expected1 = " controls: > >"; + let expected2 = " controls: > >"; + let expected3 = " controls: > >"; assert_eq!(trace(&page), expected1); swipe_up(&mut page);