mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-21 01:29:02 +00:00
feat(core/ui): eckhart: BLE event handling
[no changelog]
This commit is contained in:
parent
251c7c7c48
commit
a533bf898c
@ -1621,14 +1621,16 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// *,
|
||||
/// device_name: str,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Pairing device: first screen (device name)."""
|
||||
/// """Pairing device: first screen (device name).
|
||||
/// Returns if BLEEvent::PairingRequest is received."""
|
||||
Qstr::MP_QSTR_show_pairing_device_name => obj_fn_kw!(0, new_show_pairing_device_name).as_obj(),
|
||||
|
||||
/// def show_pairing_code(
|
||||
/// *,
|
||||
/// code: str,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Pairing device: second screen (pairing code)."""
|
||||
/// """Pairing device: second screen (pairing code).
|
||||
/// Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
||||
Qstr::MP_QSTR_show_pairing_code => obj_fn_kw!(0, new_show_pairing_code).as_obj(),
|
||||
|
||||
/// def show_info(
|
||||
|
83
core/embed/rust/src/ui/component/ble.rs
Normal file
83
core/embed/rust/src/ui/component/ble.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use crate::ui::{
|
||||
component::{Component, Event, EventCtx},
|
||||
event::BLEEvent,
|
||||
};
|
||||
|
||||
pub struct BLEHandler<T> {
|
||||
inner: T,
|
||||
waiting_for_pairing: bool,
|
||||
}
|
||||
|
||||
pub enum BLEHandlerMsg<T> {
|
||||
Content(T),
|
||||
PairingCode(u32),
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
impl<T> BLEHandler<T> {
|
||||
pub fn new(inner: T, waiting_for_pairing: bool) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
waiting_for_pairing,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Component for BLEHandler<T>
|
||||
where
|
||||
T: Component,
|
||||
{
|
||||
type Msg = BLEHandlerMsg<T::Msg>;
|
||||
|
||||
fn place(&mut self, bounds: crate::ui::geometry::Rect) -> crate::ui::geometry::Rect {
|
||||
self.inner.place(bounds)
|
||||
}
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
match (event, self.waiting_for_pairing) {
|
||||
(Event::BLE(BLEEvent::PairingRequest(num)), true) => {
|
||||
return Some(BLEHandlerMsg::PairingCode(num))
|
||||
}
|
||||
(Event::BLE(BLEEvent::PairingCanceled), false)
|
||||
| (Event::BLE(BLEEvent::Disconnected), false) => return Some(BLEHandlerMsg::Cancelled),
|
||||
_ => {}
|
||||
}
|
||||
self.inner.event(ctx, event).map(BLEHandlerMsg::Content)
|
||||
}
|
||||
|
||||
fn render<'s>(&'s self, target: &mut impl crate::ui::shape::Renderer<'s>) {
|
||||
self.inner.render(target)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl<T> crate::trace::Trace for BLEHandler<T>
|
||||
where
|
||||
T: crate::trace::Trace,
|
||||
{
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
self.inner.trace(t)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "micropython")]
|
||||
mod micropython {
|
||||
use super::*;
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::obj::Obj,
|
||||
ui::layout::{obj::ComponentMsgObj, result::CANCELLED},
|
||||
};
|
||||
impl<T> ComponentMsgObj for BLEHandler<T>
|
||||
where
|
||||
T: ComponentMsgObj,
|
||||
{
|
||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||
match msg {
|
||||
BLEHandlerMsg::Content(msg) => self.inner.msg_try_into_obj(msg),
|
||||
BLEHandlerMsg::PairingCode(num) => num.try_into(),
|
||||
BLEHandlerMsg::Cancelled => Ok(CANCELLED.as_obj()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
pub mod bar;
|
||||
pub mod base;
|
||||
#[cfg(feature = "ble")]
|
||||
mod ble;
|
||||
pub mod border;
|
||||
pub mod button_request;
|
||||
#[cfg(all(
|
||||
@ -32,6 +34,8 @@ pub mod timeout;
|
||||
|
||||
pub use bar::Bar;
|
||||
pub use base::{Child, Component, ComponentExt, Event, EventCtx, FlowMsg, Never, Timer};
|
||||
#[cfg(feature = "ble")]
|
||||
pub use ble::BLEHandler;
|
||||
pub use border::Border;
|
||||
pub use button_request::{ButtonRequestExt, SendButtonRequest};
|
||||
#[cfg(all(
|
||||
|
@ -180,6 +180,10 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
let device = screen.add_device_menu(device_name, about);
|
||||
let settings = screen.add_settings_menu(security, device);
|
||||
|
||||
let is_connected = !paired_devices.is_empty(); // TODO this is mostly bad
|
||||
let connected_subtext: Option<TString<'static>> =
|
||||
is_connected.then_some("1 device connected".into());
|
||||
|
||||
let mut paired_device_indices: Vec<usize, 1> = Vec::new();
|
||||
for (i, device) in paired_devices.iter().enumerate() {
|
||||
unwrap!(paired_device_indices
|
||||
@ -187,9 +191,10 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
}
|
||||
|
||||
let devices = screen.add_paired_devices_menu(paired_devices, paired_device_indices);
|
||||
let pair_and_connect = screen.add_pair_and_connect_menu(devices);
|
||||
let pair_and_connect = screen.add_pair_and_connect_menu(devices, connected_subtext);
|
||||
|
||||
let root = screen.add_root_menu(failed_backup, pair_and_connect, settings);
|
||||
let root =
|
||||
screen.add_root_menu(failed_backup, pair_and_connect, settings, connected_subtext);
|
||||
|
||||
screen.set_active_subscreen(root);
|
||||
|
||||
@ -219,17 +224,18 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
self.add_subscreen(Subscreen::Submenu(submenu_index))
|
||||
}
|
||||
|
||||
fn add_pair_and_connect_menu(&mut self, manage_devices_index: usize) -> usize {
|
||||
fn add_pair_and_connect_menu(
|
||||
&mut self,
|
||||
manage_devices_index: usize,
|
||||
connected_subtext: Option<TString<'static>>,
|
||||
) -> usize {
|
||||
let mut items: Vec<MenuItem, MENU_MAX_ITEMS> = Vec::new();
|
||||
unwrap!(items.push(
|
||||
MenuItem::new(
|
||||
"Manage paired devices".into(),
|
||||
Some(Action::GoTo(manage_devices_index)),
|
||||
)
|
||||
.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN)
|
||||
)))
|
||||
.with_subtext(connected_subtext.map(|t| (t, Some(Button::SUBTEXT_STYLE_GREEN))))
|
||||
));
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
"Pair new device".into(),
|
||||
@ -293,6 +299,7 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
failed_backup: bool,
|
||||
pair_and_connect_index: usize,
|
||||
settings_index: usize,
|
||||
connected_subtext: Option<TString<'static>>,
|
||||
) -> usize {
|
||||
let mut items: Vec<MenuItem, MENU_MAX_ITEMS> = Vec::new();
|
||||
if failed_backup {
|
||||
@ -310,10 +317,7 @@ impl<'a> DeviceMenuScreen<'a> {
|
||||
"Pair & connect".into(),
|
||||
Some(Action::GoTo(pair_and_connect_index)),
|
||||
)
|
||||
.with_subtext(Some((
|
||||
"1 device connected".into(),
|
||||
Some(Button::SUBTEXT_STYLE_GREEN)
|
||||
)))
|
||||
.with_subtext(connected_subtext.map(|t| (t, Some(Button::SUBTEXT_STYLE_GREEN))))
|
||||
));
|
||||
unwrap!(items.push(MenuItem::new(
|
||||
"Settings".into(),
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
Paragraphs, VecExt,
|
||||
},
|
||||
},
|
||||
Empty, FormattedText,
|
||||
BLEHandler, Empty, FormattedText,
|
||||
},
|
||||
geometry::{Alignment, LinearPlacement, Offset},
|
||||
layout::{
|
||||
@ -814,6 +814,7 @@ impl FirmwareUI for UIEckhart {
|
||||
.with_action_bar(ActionBar::new_single(Button::with_text(
|
||||
"Continue on host".into(),
|
||||
)));
|
||||
let screen = BLEHandler::new(screen, true);
|
||||
let layout = RootComponent::new(screen);
|
||||
Ok(layout)
|
||||
}
|
||||
@ -828,6 +829,7 @@ impl FirmwareUI for UIEckhart {
|
||||
let screen = TextScreen::new(FormattedText::new(ops))
|
||||
.with_header(Header::new("Bluetooth pairing".into()))
|
||||
.with_action_bar(ActionBar::new_cancel_confirm());
|
||||
let screen = BLEHandler::new(screen, false);
|
||||
let layout = RootComponent::new(screen);
|
||||
Ok(layout)
|
||||
}
|
||||
|
@ -549,7 +549,8 @@ def show_pairing_device_name(
|
||||
*,
|
||||
device_name: str,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Pairing device: first screen (device name)."""
|
||||
"""Pairing device: first screen (device name).
|
||||
Returns if BLEEvent::PairingRequest is received."""
|
||||
|
||||
|
||||
# rust/src/ui/api/firmware_micropython.rs
|
||||
@ -557,7 +558,8 @@ def show_pairing_code(
|
||||
*,
|
||||
code: str,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Pairing device: second screen (pairing code)."""
|
||||
"""Pairing device: second screen (pairing code).
|
||||
Returns on BLEEvent::{PairingCanceled, Disconnected}."""
|
||||
|
||||
|
||||
# rust/src/ui/api/firmware_micropython.rs
|
||||
|
Loading…
Reference in New Issue
Block a user