Skip to content

Commit 0e925b3

Browse files
committed
wip async bip39 unlock + animation
1 parent aaece46 commit 0e925b3

File tree

11 files changed

+96
-253
lines changed

11 files changed

+96
-253
lines changed

src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ set(DBB-FIRMWARE-USB-SOURCES ${DBB-FIRMWARE-USB-SOURCES} PARENT_SCOPE)
5353
set(DBB-FIRMWARE-UI-SOURCES
5454
${CMAKE_SOURCE_DIR}/src/screen.c
5555
${CMAKE_SOURCE_DIR}/src/ui/graphics/graphics.c
56-
${CMAKE_SOURCE_DIR}/src/ui/graphics/lock_animation.c
5756
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
5857
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
5958
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X10.c

src/rust/bitbox02-rust/src/workflow/unlock.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ pub async fn unlock_keystore(
8080
title: &str,
8181
can_cancel: password::CanCancel,
8282
) -> Result<(), UnlockError> {
83-
super::unlock_animation::animate().await;
84-
8583
let password = password::enter(
8684
hal,
8785
title,
@@ -135,16 +133,24 @@ pub async fn unlock_bip39(hal: &mut impl crate::hal::Hal, seed: &[u8]) {
135133
}
136134
}
137135

138-
let result = bitbox02::ui::with_lock_animation(async || {
136+
let ((), result) = util::bb02_async::join(
137+
super::unlock_animation::animate(),
139138
keystore::unlock_bip39(
140139
crate::secp256k1::SECP256K1,
141140
seed,
142141
&mnemonic_passphrase,
142+
// idx goes from 0..=2047, but for the simulator, we don't yield at all, otherwise
143+
// unlock becomes very slow in the simulator.
144+
#[cfg(feature = "c-unit-testing")]
145+
async |_idx| {},
146+
// idx goes from 0..=2047, but we yield every time to keep the processing time per
147+
// iteration to a minimum.
148+
#[cfg(not(feature = "c-unit-testing"))]
143149
async |_idx| util::bb02_async::yield_now().await,
144-
)
145-
.await
146-
})
150+
),
151+
)
147152
.await;
153+
148154
if result.is_err() {
149155
abort("bip39 unlock failed");
150156
}

src/rust/bitbox02-sys/build.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ const ALLOWLIST_FNS: &[&str] = &[
8686
"keystore_test_get_retained_bip39_seed_encrypted",
8787
"label_create",
8888
"localtime",
89-
"lock_animation_start",
90-
"lock_animation_stop",
9189
"memory_set_salt_root",
9290
"memory_add_noise_remote_static_pubkey",
9391
"memory_bootloader_hash",
@@ -215,6 +213,7 @@ const BITBOX02_SOURCES: &[&str] = &[
215213
"src/ui/components/label.c",
216214
"src/ui/components/left_arrow.c",
217215
"src/ui/components/lockscreen.c",
216+
"src/ui/components/unlock_animation.c",
218217
"src/ui/components/menu.c",
219218
"src/ui/components/orientation_arrows.c",
220219
"src/ui/components/progress.c",
@@ -238,7 +237,6 @@ const BITBOX02_SOURCES: &[&str] = &[
238237
"src/ui/fonts/password_11X12.c",
239238
"src/ui/fonts/password_9X9.c",
240239
"src/ui/graphics/graphics.c",
241-
"src/ui/graphics/lock_animation.c",
242240
"src/ui/oled/sh1107.c",
243241
"src/ui/oled/ssd1312.c",
244242
"src/ui/screen_process.c",

src/rust/bitbox02-sys/wrapper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#include <ui/fonts/font_a_9X9.h>
4545
#include <ui/fonts/monogram_5X9.h>
4646
#include <ui/fonts/password_11X12.h>
47-
#include <ui/graphics/lock_animation.h>
4847
#include <ui/oled/oled.h>
4948
#include <ui/screen_process.h>
5049
#include <ui/screen_saver.h>

src/rust/bitbox02/src/ui/ui.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -436,13 +436,6 @@ pub fn trinary_input_string_set_input(component: &mut Component, word: &str) {
436436
}
437437
}
438438

439-
pub async fn with_lock_animation<F: AsyncFn() -> R, R>(f: F) -> R {
440-
unsafe { bitbox02_sys::lock_animation_start() };
441-
let result = f().await;
442-
unsafe { bitbox02_sys::lock_animation_stop() };
443-
result
444-
}
445-
446439
pub fn screen_stack_pop_all() {
447440
unsafe {
448441
bitbox02_sys::ui_screen_stack_pop_all();

src/rust/bitbox02/src/ui/ui_stub.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ pub fn trinary_input_string_set_input(_component: &mut Component, _word: &str) {
119119
panic!("not used")
120120
}
121121

122-
pub fn with_lock_animation<F: Fn() -> R, R>(f: F) -> R {
123-
f()
124-
}
125-
126122
pub fn screen_stack_pop_all() {}
127123

128124
pub fn progress_create<'a>(_title: &str) -> Component<'a> {
@@ -140,3 +136,14 @@ pub fn empty_create<'a>() -> Component<'a> {
140136
_p: PhantomData,
141137
}
142138
}
139+
140+
pub fn unlock_animation_create<'a, F>(mut on_done: F) -> Component<'a>
141+
where
142+
F: FnMut() + 'a,
143+
{
144+
on_done();
145+
Component {
146+
is_pushed: false,
147+
_p: PhantomData,
148+
}
149+
}

src/rust/bitbox02/src/ui/ui_stub_c_unit_tests.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,6 @@ pub fn trinary_input_string_set_input(_component: &mut Component, _word: &str) {
162162
panic!("not implemented")
163163
}
164164

165-
pub fn with_lock_animation<F: Fn() -> R, R>(f: F) -> R {
166-
f()
167-
}
168-
169165
pub fn screen_stack_pop_all() {}
170166

171167
pub fn progress_create<'a>(_title: &str) -> Component<'a> {
@@ -183,3 +179,14 @@ pub fn empty_create<'a>() -> Component<'a> {
183179
_p: PhantomData,
184180
}
185181
}
182+
183+
pub fn unlock_animation_create<'a, F>(mut on_done: F) -> Component<'a>
184+
where
185+
F: FnMut() + 'a,
186+
{
187+
on_done();
188+
Component {
189+
is_pushed: false,
190+
_p: PhantomData,
191+
}
192+
}

src/rust/util/src/bb02_async.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,57 @@ pub fn yield_now() -> impl core::future::Future<Output = ()> {
7171
}
7272
})
7373
}
74+
75+
/// Executes both futures in tandem, returning the results of both when both are done.
76+
pub fn join<O1, O2>(
77+
fut1: impl core::future::Future<Output = O1>,
78+
fut2: impl core::future::Future<Output = O2>,
79+
) -> impl core::future::Future<Output = (O1, O2)> {
80+
let mut fut1 = Box::pin(fut1);
81+
let mut fut2 = Box::pin(fut2);
82+
83+
let mut result1 = None;
84+
let mut result2 = None;
85+
86+
core::future::poll_fn(move |cx| {
87+
if result1.is_none() {
88+
if let Poll::Ready(res) = fut1.as_mut().poll(cx) {
89+
result1 = Some(res);
90+
}
91+
}
92+
93+
if result2.is_none() {
94+
if let Poll::Ready(res) = fut2.as_mut().poll(cx) {
95+
result2 = Some(res);
96+
}
97+
}
98+
99+
if result1.is_some() && result2.is_some() {
100+
Poll::Ready((result1.take().unwrap(), result2.take().unwrap()))
101+
} else {
102+
Poll::Pending
103+
}
104+
})
105+
}
106+
107+
#[cfg(test)]
108+
mod tests {
109+
use super::*;
110+
111+
#[test]
112+
fn test_join() {
113+
async fn f1() -> i32 {
114+
-42
115+
}
116+
117+
async fn f2() -> Box<u32> {
118+
yield_now().await;
119+
yield_now().await;
120+
yield_now().await;
121+
Box::new(42)
122+
}
123+
124+
assert_eq!(block_on(join(f1(), f2())), (-42, Box::new(42)));
125+
assert_eq!(block_on(join(f2(), f1())), (Box::new(42), -42));
126+
}
127+
}

src/ui/components/unlock_animation.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <hardfault.h>
1818
#include <screen.h>
1919
#include <ui/component.h>
20+
#include <ui/screen_process.h>
2021
#include <ui/ui_util.h>
2122

2223
#include <stdint.h>
@@ -25,7 +26,11 @@
2526
// This many iterations times the slowdown factor to render the whole animation.
2627
#define LOCK_ANIMATION_N_FRAMES (38)
2728

28-
#define SLOWDOWN_FACTOR (10)
29+
// Since BIP39 unlock takes 2048 iterations, and the screen frame rate is 30 (SCREEN_FRAME_RATE,
30+
// render is called only every 30th iteration), if we want both to finish at the same time, the
31+
// slowdown factor becomes the following. 1 is subtracted so the animation takes longer, not
32+
// shorter, than the actual unlock.
33+
#define SLOWDOWN_FACTOR (2048 / ((float)LOCK_ANIMATION_N_FRAMES * (float)SCREEN_FRAME_RATE - 1))
2934

3035
#define LOCK_ANIMATION_FRAME_WIDTH (28)
3136
#define LOCK_ANIMATION_FRAME_HEIGHT (25)
@@ -159,7 +164,7 @@ static void _render(component_t* component)
159164
data_t* data = (data_t*)component->data;
160165
int frame = data->frame / SLOWDOWN_FACTOR;
161166

162-
if (frame == LOCK_ANIMATION_N_FRAMES) {
167+
if (frame >= LOCK_ANIMATION_N_FRAMES) {
163168
/* End of the animation */
164169
if (data->on_done) {
165170
data->on_done(data->on_done_param);

0 commit comments

Comments
 (0)