1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-25 16:08:32 +00:00

fixup! feat(core/rust): homescreen background

This commit is contained in:
tychovrahe 2022-11-20 13:32:51 +01:00
parent 7fcc029444
commit 5bd9504826
3 changed files with 84 additions and 26 deletions

View File

@ -1,6 +1,6 @@
use core::{ use core::{
alloc::Layout, alloc::Layout,
ops::Deref, ops::{Deref, DerefMut},
ptr::{self, NonNull}, ptr::{self, NonNull},
}; };
@ -38,6 +38,33 @@ impl<T> Gc<T> {
} }
} }
impl<T: Default> Gc<[T]> {
/// Allocate slice on the heap managed by the MicroPython garbage collector
/// and fill with default values.
pub fn new_slice(len: usize) -> Result<Self, Error> {
let layout = Layout::array::<T>(len).unwrap();
// TODO: Assert that `layout.align()` is the same as the GC alignment.
// SAFETY:
// - Unfortunately we cannot respect `layout.align()` as MicroPython GC does
// not support custom alignment.
// - `ptr` is guaranteed to stay valid as long as it's reachable from the stack
// or the MicroPython heap.
// EXCEPTION: Returns null instead of raising.
unsafe {
let raw = ffi::gc_alloc(layout.size(), 0);
if raw.is_null() {
return Err(Error::AllocationFailed);
}
let typed: *mut T = raw.cast();
for i in 0..len {
ptr::write(typed.add(i), T::default());
}
let array_ptr = ptr::slice_from_raw_parts_mut(typed, len);
Ok(Self::from_raw(array_ptr as _))
}
}
}
impl<T: ?Sized> Gc<T> { impl<T: ?Sized> Gc<T> {
/// Construct a `Gc` from a raw pointer. /// Construct a `Gc` from a raw pointer.
/// ///
@ -82,3 +109,9 @@ impl<T: ?Sized> Deref for Gc<T> {
unsafe { self.0.as_ref() } unsafe { self.0.as_ref() }
} }
} }
impl<T: ?Sized> DerefMut for Gc<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.0.as_mut() }
}
}

View File

@ -1,8 +1,6 @@
use crate::{ use crate::trezorhal::storage::{get, get_length};
micropython::ffi,
trezorhal::storage::{get, get_length}, pub const HOMESCREEN_MAX_SIZE: usize = 16384;
};
use core::slice;
const STORAGE_VERSION_01: u8 = 1; const STORAGE_VERSION_01: u8 = 1;
const STORAGE_VERSION_02: u8 = 2; const STORAGE_VERSION_02: u8 = 2;
@ -36,20 +34,26 @@ const INITIALIZED: u16 = FLAG_PUBLIC | APP_DEVICE | 0x0013;
const SAFETY_CHECK_LEVEL: u16 = APP_DEVICE | 0x0014; const SAFETY_CHECK_LEVEL: u16 = APP_DEVICE | 0x0014;
const EXPERIMENTAL_FEATURES: u16 = APP_DEVICE | 0x0015; const EXPERIMENTAL_FEATURES: u16 = APP_DEVICE | 0x0015;
pub fn get_avatar() -> Result<&'static mut [u8], ()> { pub fn get_avatar_len() -> Result<usize, ()> {
let avatar_len_res = get_length(HOMESCREEN);
if let Ok(len) = avatar_len_res {
Ok(len)
} else {
Err(())
}
}
pub fn get_avatar(buffer: &mut [u8]) -> Result<usize, ()> {
let avatar_len_res = get_length(HOMESCREEN); let avatar_len_res = get_length(HOMESCREEN);
return if let Ok(len) = avatar_len_res { if let Ok(len) = avatar_len_res {
let data_ptr_raw = unsafe { ffi::gc_alloc(len, 0) };
let buffer = unsafe { slice::from_raw_parts_mut(data_ptr_raw as _, len) };
if len <= buffer.len() { if len <= buffer.len() {
unwrap!(get(HOMESCREEN, buffer)); unwrap!(get(HOMESCREEN, buffer));
Ok(&mut buffer[..len]) Ok(len)
} else { } else {
Err(()) Err(())
} }
} else { } else {
Err(()) Err(())
}; }
} }

View File

@ -1,7 +1,8 @@
mod render; mod render;
use crate::{ use crate::{
storage::get_avatar, micropython::gc::Gc,
storage::{get_avatar, get_avatar_len},
time::{Duration, Instant}, time::{Duration, Instant},
trezorhal::usb::usb_configured, trezorhal::usb::usb_configured,
ui::{ ui::{
@ -192,12 +193,22 @@ where
let notification = self.get_notification(); let notification = self.get_notification();
homescreen( let res = get_image();
get_image(), if let Ok(data) = res {
texts, homescreen(
notification, data.as_ref(),
self.paint_notification_only, texts,
); notification,
self.paint_notification_only,
);
} else {
homescreen(
IMAGE_HOMESCREEN,
texts,
notification,
self.paint_notification_only,
);
}
} }
} }
@ -277,16 +288,26 @@ where
icon: None icon: None
}, },
],)); ],));
homescreen_blurred(get_image(), texts);
let res = get_image();
if let Ok(data) = res {
homescreen_blurred(data.as_ref(), texts);
} else {
homescreen_blurred(IMAGE_HOMESCREEN, texts);
}
} }
} }
fn get_image() -> &'static [u8] { fn get_image() -> Result<Gc<[u8]>, ()> {
if let Ok(data) = get_avatar() { if let Ok(len) = get_avatar_len() {
data let result = Gc::<[u8]>::new_slice(len);
} else { if let Ok(mut buffer) = result {
IMAGE_HOMESCREEN if get_avatar(buffer.as_mut()).is_ok() {
return Ok(buffer);
}
}
} }
Err(())
} }
#[cfg(feature = "ui_debug")] #[cfg(feature = "ui_debug")]