What changed, and why it matters
This commit is a routine internal code reorganization. It moves the device's startup orientation screen logic from a general workflow module into a hardware-abstraction trait so different device variants can define their own startup behavior. There is no user-facing security change, no bug fix, and no indication this addresses a vulnerability.
No security action required. Treat as normal refactoring/development commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces a startup() async method on the bitbox_hal::System trait and implements it for BitBox02System with the existing orientation-screen behavior (choose orientation, rotate screen, delay, switch to lockscreen). The main loop now calls H::System::startup() instead of the removed workflow::orientation_screen::orientation_screen(). Simulators are updated to use the new trait method. The logic is functionally identical; only the abstraction layer changed.
Changed components
src/rust/bitbox-hal/src/system.rssrc/rust/bitbox02/src/hal/system.rssrc/rust/bitbox02-rust/src/main_loop.rssrc/rust/bitbox02-rust/src/workflow.rssrc/rust/bitbox02-rust/src/workflow/orientation_screen.rssrc/rust/bitbox02-rust/src/hal/testing/system.rstest/simulator-graphical/src/main.rstest/simulator-graphical-bb03/src/main.rsInspect captured patch +41 / −46
diff --git a/src/rust/bitbox-hal/src/system.rs b/src/rust/bitbox-hal/src/system.rs
index a2e6bee..c04a0f1 100644
--- a/src/rust/bitbox-hal/src/system.rs
+++ b/src/rust/bitbox-hal/src/system.rs
@@ -1,5 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
+#[allow(async_fn_in_trait)]
pub trait System {
+ /// Runs device-specific startup UI/initialization before regular operation.
+ async fn startup();
+
fn reboot_to_bootloader(&mut self) -> !;
}
diff --git a/src/rust/bitbox02-rust/src/hal/testing/system.rs b/src/rust/bitbox02-rust/src/hal/testing/system.rs
index e68e2db..804bbd9 100644
--- a/src/rust/bitbox02-rust/src/hal/testing/system.rs
+++ b/src/rust/bitbox02-rust/src/hal/testing/system.rs
@@ -9,6 +9,8 @@ impl TestingSystem {
}
impl crate::hal::System for TestingSystem {
+ async fn startup() {}
+
fn reboot_to_bootloader(&mut self) -> ! {
panic!("reboot_to_bootloader called")
}
diff --git a/src/rust/bitbox02-rust/src/main_loop.rs b/src/rust/bitbox02-rust/src/main_loop.rs
index 3d46334..54482f0 100644
--- a/src/rust/bitbox02-rust/src/main_loop.rs
+++ b/src/rust/bitbox02-rust/src/main_loop.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
-use crate::hal::Memory;
+use crate::hal::{Memory, System};
use alloc::boxed::Box;
use bitbox_executor::Executor;
use bitbox02::ringbuffer::RingBuffer;
@@ -20,8 +20,8 @@ pub fn spawn(fut: DynExecutorFuture) {
EXECUTOR.spawn(fut).detach();
}
-pub fn main_loop(hal: &mut impl crate::hal::Hal) -> ! {
- static ORIENTATION_CHOSEN: AtomicBool = AtomicBool::new(false);
+pub fn main_loop<H: crate::hal::Hal>(hal: &mut H) -> ! {
+ static STARTUP_COMPLETE: AtomicBool = AtomicBool::new(false);
// Set the size of uart_read_buf to the size of the ringbuffer in the UART driver so we can read
// out all bytes
@@ -36,10 +36,10 @@ pub fn main_loop(hal: &mut impl crate::hal::Hal) -> ! {
let device_name = hal.memory().get_device_name();
bitbox02::da14531::set_name(&device_name, &mut uart_write_queue);
- // This starts the async orientation screen workflow, which is processed by the loop below.
+ // This starts the async startup workflow, which is processed by the loop below.
spawn(Box::pin(async {
- crate::workflow::orientation_screen::orientation_screen().await;
- ORIENTATION_CHOSEN.store(true, Ordering::Relaxed);
+ H::System::startup().await;
+ STARTUP_COMPLETE.store(true, Ordering::Relaxed);
}));
let mut hww_data = None;
@@ -161,7 +161,7 @@ pub fn main_loop(hal: &mut impl crate::hal::Hal) -> ! {
// Run async executor
EXECUTOR.try_tick();
- if ORIENTATION_CHOSEN.swap(false, Ordering::Relaxed) {
+ if STARTUP_COMPLETE.swap(false, Ordering::Relaxed) {
// hww handler in usb_process must be setup before we can allow ble connections
if let Ok(crate::hal::memory::Platform::BitBox02Plus) = hal.memory().get_platform() {
let product = bitbox02::platform::product();
diff --git a/src/rust/bitbox02-rust/src/workflow.rs b/src/rust/bitbox02-rust/src/workflow.rs
index 527c479..2237bea 100644
--- a/src/rust/bitbox02-rust/src/workflow.rs
+++ b/src/rust/bitbox02-rust/src/workflow.rs
@@ -5,7 +5,6 @@
path = "workflow/mnemonic_c_unit_tests.rs"
)]
pub mod mnemonic;
-pub mod orientation_screen;
pub mod pairing;
pub mod password;
pub mod transaction;
diff --git a/src/rust/bitbox02-rust/src/workflow/orientation_screen.rs b/src/rust/bitbox02-rust/src/workflow/orientation_screen.rs
deleted file mode 100644
index 210a380..0000000
--- a/src/rust/bitbox02-rust/src/workflow/orientation_screen.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-use bitbox02::delay::delay_for;
-use bitbox02::ui::choose_orientation;
-use core::time::Duration;
-
-pub async fn orientation_screen() -> bool {
- let upside_down = choose_orientation().await;
- if upside_down {
- bitbox02::screen_rotate()
- }
-
- // During this delay the bb02 logotype is shown
- delay_for(Duration::from_millis(1300)).await;
-
- // Switch to lockscreen that shows "See the bitbox app" and device name
- bitbox02::ui::screen_process_waiting_switch_to_lockscreen();
-
- upside_down
-}
diff --git a/src/rust/bitbox02/src/hal/system.rs b/src/rust/bitbox02/src/hal/system.rs
index 4f53c3b..a81efdc 100644
--- a/src/rust/bitbox02/src/hal/system.rs
+++ b/src/rust/bitbox02/src/hal/system.rs
@@ -1,10 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
use bitbox_hal::System;
+use core::time::Duration;
pub struct BitBox02System;
impl System for BitBox02System {
+ async fn startup() {
+ let upside_down = crate::ui::choose_orientation().await;
+ if upside_down {
+ crate::screen_rotate();
+ }
+
+ // During this delay the bb02 logotype is shown.
+ crate::delay::delay_for(Duration::from_millis(1300)).await;
+
+ // Switch to lockscreen that shows "See the bitbox app" and device name.
+ crate::ui::screen_process_waiting_switch_to_lockscreen();
+ }
+
fn reboot_to_bootloader(&mut self) -> ! {
crate::reboot_to_bootloader()
}
diff --git a/test/simulator-graphical-bb03/src/main.rs b/test/simulator-graphical-bb03/src/main.rs
index 6cfe487..d332c46 100644
--- a/test/simulator-graphical-bb03/src/main.rs
+++ b/test/simulator-graphical-bb03/src/main.rs
@@ -38,7 +38,7 @@ use tracing::{debug, error, info};
use tracing_subscriber::{EnvFilter, filter::LevelFilter, fmt, prelude::*};
use bitbox02::ui::ugui::UG_COLOR;
-use bitbox02_rust::hal::{Hal, Memory};
+use bitbox02_rust::hal::{Hal, Memory, System};
// Explicitly link library for its C exports
extern crate bitbox02_rust_c;
@@ -184,7 +184,7 @@ struct App {
cursor_pos: (i32, i32),
outbound_in: Option<mpsc::Sender<[u8; 64]>>,
inbound_out: Option<mpsc::Receiver<[u8; 64]>>,
- orientation_task: Option<util::bb02_async::Task<'static, bool>>,
+ startup_task: Option<util::bb02_async::Task<'static, ()>>,
}
impl Default for App {
@@ -200,7 +200,7 @@ impl Default for App {
cursor_pos: (0, 0),
outbound_in: Default::default(),
inbound_out: Default::default(),
- orientation_task: Default::default(),
+ startup_task: Default::default(),
}
}
}
@@ -528,10 +528,10 @@ impl ApplicationHandler<UserEvent> for App {
bitbox02::usb_processing::process_hww();
bitbox02::screen::process();
- if let Some(ref mut task) = self.orientation_task {
- if let Ready(_orientation) = util::bb02_async::spin(task) {
+ if let Some(ref mut task) = self.startup_task {
+ if let Ready(_startup) = util::bb02_async::spin(task) {
ACCEPTING_CONNECTIONS.store(true, Ordering::Relaxed);
- self.orientation_task = None;
+ self.startup_task = None;
}
}
@@ -560,9 +560,7 @@ impl ApplicationHandler<UserEvent> for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.create_window(event_loop, None)
.expect("failed to create initial window");
- self.orientation_task = Some(Box::pin(
- bitbox02_rust::workflow::orientation_screen::orientation_screen(),
- ));
+ self.startup_task = Some(Box::pin(bitbox02::hal::system::BitBox02System::startup()));
}
}
diff --git a/test/simulator-graphical/src/main.rs b/test/simulator-graphical/src/main.rs
index f92eea1..9ad349a 100644
--- a/test/simulator-graphical/src/main.rs
+++ b/test/simulator-graphical/src/main.rs
@@ -39,7 +39,7 @@ use tracing::{debug, error, info};
use tracing_subscriber::{EnvFilter, filter::LevelFilter, fmt, prelude::*};
use bitbox02::ui::ugui::UG_COLOR;
-use bitbox02_rust::hal::{Hal, Memory};
+use bitbox02_rust::hal::{Hal, Memory, System};
// Explicitly link library for its C exports
extern crate bitbox02_rust_c;
@@ -220,7 +220,7 @@ struct App {
mouse_last_y: i32,
outbound_in: Option<mpsc::Sender<[u8; 64]>>,
inbound_out: Option<mpsc::Receiver<[u8; 64]>>,
- orientation_task: Option<util::bb02_async::Task<'static, bool>>,
+ startup_task: Option<util::bb02_async::Task<'static, ()>>,
}
impl Default for App {
@@ -239,7 +239,7 @@ impl Default for App {
mouse_last_y: 0,
outbound_in: Default::default(),
inbound_out: Default::default(),
- orientation_task: Default::default(),
+ startup_task: Default::default(),
}
}
}
@@ -659,10 +659,10 @@ impl ApplicationHandler<UserEvent> for App {
bitbox02::usb_processing::process_hww();
bitbox02::screen::process();
- if let Some(ref mut task) = self.orientation_task {
- if let Ready(_orientation) = util::bb02_async::spin(task) {
+ if let Some(ref mut task) = self.startup_task {
+ if let Ready(_startup) = util::bb02_async::spin(task) {
ACCEPTING_CONNECTIONS.store(true, Ordering::Relaxed);
- self.orientation_task = None;
+ self.startup_task = None;
}
}
@@ -691,9 +691,7 @@ impl ApplicationHandler<UserEvent> for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.create_window(event_loop, None)
.expect("failed to create initial window");
- self.orientation_task = Some(Box::pin(
- bitbox02_rust::workflow::orientation_screen::orientation_screen(),
- ));
+ self.startup_task = Some(Box::pin(bitbox02::hal::system::BitBox02System::startup()));
}
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.