diff --git a/src/rust/bitbox02-rust/src/hww.rs b/src/rust/bitbox02-rust/src/hww.rs index c9f751186..99c4056be 100644 --- a/src/rust/bitbox02-rust/src/hww.rs +++ b/src/rust/bitbox02-rust/src/hww.rs @@ -110,6 +110,13 @@ fn api_attestation(usb_in: &[u8]) -> Vec { } async fn _process_packet(hal: &mut impl crate::hal::Hal, usb_in: Vec) -> Vec { + // Update the waiting screen from "See the BitBoxApp" to the logo, now that the host is + // connected. When the device is initialized, we delay this until the unlock call, otherwise + // there would be a flicker where the logo would be shown before the host invokes unlock. + if !bitbox02::memory::is_initialized() || usb_in.as_slice() == [OP_UNLOCK] { + bitbox02::ui::screen_process_waiting_switch_to_logo(); + } + match usb_in.split_first() { Some((&OP_UNLOCK, b"")) => return api_unlock(hal).await, Some((&OP_ATTESTATION, rest)) => return api_attestation(rest), diff --git a/src/rust/bitbox02-rust/src/hww/noise.rs b/src/rust/bitbox02-rust/src/hww/noise.rs index 9ee315622..df063d0c7 100644 --- a/src/rust/bitbox02-rust/src/hww/noise.rs +++ b/src/rust/bitbox02-rust/src/hww/noise.rs @@ -82,8 +82,6 @@ pub(crate) async fn process( ) -> Result<(), Error> { match usb_in.split_first() { Some((&OP_I_CAN_HAS_HANDSHAEK, b"")) => { - // The previous screen was "See the BitBoxApp". - // Since a handshake was requested, a client was connected, so we pop that screen. // Pairing is the start of a session, so we clean the screen stack in case // we started a new session in the middle of something. bitbox02::ui::screen_stack_pop_all(); diff --git a/src/rust/bitbox02-sys/build.rs b/src/rust/bitbox02-sys/build.rs index 1e287cac6..0215dbfe3 100644 --- a/src/rust/bitbox02-sys/build.rs +++ b/src/rust/bitbox02-sys/build.rs @@ -129,6 +129,7 @@ const ALLOWLIST_FNS: &[&str] = &[ "reset_ble", "screen_print_debug", "screen_process", + "screen_process_waiting_switch_to_logo", "screen_saver_disable", "screen_saver_enable", "sd_card_inserted", diff --git a/src/rust/bitbox02/src/ui.rs b/src/rust/bitbox02/src/ui.rs index e202ba68f..507845c43 100644 --- a/src/rust/bitbox02/src/ui.rs +++ b/src/rust/bitbox02/src/ui.rs @@ -25,3 +25,7 @@ mod types; mod ui; pub use ui::*; + +pub fn screen_process_waiting_switch_to_logo() { + unsafe { bitbox02_sys::screen_process_waiting_switch_to_logo() } +} diff --git a/src/ui/components/waiting.c b/src/ui/components/waiting.c index 88b751378..409d478d8 100644 --- a/src/ui/components/waiting.c +++ b/src/ui/components/waiting.c @@ -13,6 +13,7 @@ // limitations under the License. #include "waiting.h" +#include "lockscreen.h" #include "image.h" #include "ui_images.h" @@ -21,13 +22,12 @@ #include #include +#include #include -static void _render(component_t* component) -{ - // TODO - add an interesting animation? - ui_util_component_render_subcomponents(component); -} +typedef struct { + bool show_logo; +} data_t; /********************************** Component Functions **********************************/ @@ -36,7 +36,7 @@ static void _render(component_t* component) */ static component_functions_t _component_functions = { .cleanup = ui_util_component_cleanup, - .render = _render, + .render = ui_util_component_render_subcomponents, .on_event = NULL, }; @@ -47,6 +47,12 @@ static component_functions_t _component_functions = { */ component_t* waiting_create(void) { + data_t* data = malloc(sizeof(data_t)); + if (!data) { + Abort("Error: malloc waiting data"); + } + memset(data, 0, sizeof(data_t)); + component_t* waiting = malloc(sizeof(component_t)); if (!waiting) { Abort("Error: malloc waiting"); @@ -57,6 +63,29 @@ component_t* waiting_create(void) waiting->dimension.height = SCREEN_HEIGHT; waiting->position.top = 0; waiting->position.left = 0; + waiting->data = data; + + ui_util_add_sub_component(waiting, lockscreen_create()); + + return waiting; +} + +void waiting_switch_to_logo(component_t* component) +{ + data_t* data = (data_t*)component->data; + if (data->show_logo) { + return; + } + data->show_logo = true; + + if (component->sub_components.amount != 1) { + // Sanity check to avoid memory bugs, should never happen. + Abort("waiting_switch_to_logo"); + return; + } + + ui_util_component_cleanup(component->sub_components.sub_components[0]); + image_logo_data_t logo = image_logo_data(); component_t* bb2_logo = image_create( logo.buffer.data, @@ -64,7 +93,7 @@ component_t* waiting_create(void) logo.dimensions.width, logo.dimensions.height, CENTER, - waiting); - ui_util_add_sub_component(waiting, bb2_logo); - return waiting; + component); + + component->sub_components.sub_components[0] = bb2_logo; } diff --git a/src/ui/components/waiting.h b/src/ui/components/waiting.h index 50916dced..6fecc9d05 100644 --- a/src/ui/components/waiting.h +++ b/src/ui/components/waiting.h @@ -18,8 +18,14 @@ #include /** - * Creates a waiting screen. + * Creates a waiting screen. It starts out with a lockscreen (see lockscreen.c). Once + * `waiting_switch_to_logo()` is called, the waiting screen will switch to showing the logo image. */ component_t* waiting_create(void); +/** + * Switch the waiting screen to show the BitBox logo instead. + */ +void waiting_switch_to_logo(component_t* component); + #endif diff --git a/src/ui/screen_process.c b/src/ui/screen_process.c index c92757456..52caacbce 100644 --- a/src/ui/screen_process.c +++ b/src/ui/screen_process.c @@ -32,16 +32,21 @@ void ui_screen_render_component(component_t* component) UG_SendBuffer(); } +static component_t* _waiting_screen = NULL; static component_t* _get_waiting_screen(void) { - static component_t* waiting_screen = NULL; - if (waiting_screen == NULL) { - waiting_screen = waiting_create(); - if (waiting_screen == NULL) { + if (_waiting_screen == NULL) { + _waiting_screen = waiting_create(); + if (_waiting_screen == NULL) { Abort("Could not create\nwaiting screen"); } } - return waiting_screen; + return _waiting_screen; +} + +void screen_process_waiting_switch_to_logo(void) +{ + waiting_switch_to_logo(_get_waiting_screen()); } component_t* screen_process_get_top_component(void) diff --git a/src/ui/screen_process.h b/src/ui/screen_process.h index 0f26ed9b5..699754bda 100644 --- a/src/ui/screen_process.h +++ b/src/ui/screen_process.h @@ -27,6 +27,11 @@ void ui_screen_render_component(component_t* component); */ component_t* screen_process_get_top_component(void); +/** + * Wraps `waiting_switch_to_logo()` for the waiting screen. + */ +void screen_process_waiting_switch_to_logo(void); + /** * Runs the UI once. * diff --git a/src/workflow/orientation_screen.c b/src/workflow/orientation_screen.c index 011390e03..5a0a2e093 100644 --- a/src/workflow/orientation_screen.c +++ b/src/workflow/orientation_screen.c @@ -73,7 +73,6 @@ static void _idle_timer_cb(const struct timer_task* const timer_task) } usb_start(); - ui_screen_stack_push(lockscreen_create()); } #endif