gui_server_api/
navigation.rs1use hex_literal::hex;
5use server::{CheckedPermissions, MessageAllowed};
6use xous::AppId;
7
8use crate::error::NavigationError;
9use crate::msg::{
10 FinishResponse, GetPendingNavRequest, NavigateTo, NavigationCancel, NavigationResult, RunApp,
11 RunAppResponse, ShowModal,
12};
13use crate::navigation::securitykeys::{SecurityKeysNavRequest, UserPresenceOptions, UserPresenceResult};
14use crate::{GuiApi, GuiApiLight, GuiServerError, ModalStyle};
15
16pub mod alerts;
17pub mod filepicker;
18pub mod lockscreen;
19pub mod qrscanner;
20pub mod securitykeys;
21
22pub const QR_SCANNER_APP_ID: AppId = AppId(hex!("6775692d6170702d6578616d706c652e"));
23pub const FILE_BROWSER_APP_ID: AppId = AppId(hex!("46696c652042726f7773657200000000"));
24pub const SECURITY_KEYS_APP_ID: AppId = AppId(hex!("5365637572697479204b657973000000"));
25pub const LOCK_SCREEN_APP_ID: AppId = AppId(hex!("0a000000000000000000000000000000"));
26pub const ONBOARDING_APP_ID: AppId = AppId(hex!("dac5321775d449c11bc9c90f38067f8f"));
27pub const ALERTS_APP_ID: AppId = AppId(hex!("32defc0867555fe8002759667000b22a"));
28pub const BITCOIN_APP_ID: AppId = AppId(hex!("426974636f696e2057616c6c65740000"));
29pub const SETTINGS_APP_ID: AppId = AppId(hex!("c192b79230473875f159d4423d74d00f"));
30
31impl<P: CheckedPermissions> GuiApiLight<P> {
32 pub fn show_modal(
34 &self,
35 app_id: AppId,
36 modal_style: ModalStyle,
37 args: &[u8],
38 ) -> Result<NavigationResult, GuiServerError>
39 where
40 P: MessageAllowed<ShowModal>,
41 {
42 let nav_req = ShowModal { modal_style, app_id, args: args.to_vec() };
43 let response = self.conn.try_send_blocking_archive(nav_req)?;
44 Ok(response.or_else(|_| Err(NavigationError::RequestBufferTooSmall)))
45 }
46
47 pub fn navigate_to(&self, app_id: AppId, args: &[u8]) -> Result<NavigationResult, GuiServerError>
49 where
50 P: MessageAllowed<NavigateTo>,
51 {
52 let nav_req = NavigateTo { app_id, args: args.to_vec() };
53 let response = self.conn.try_send_blocking_archive(nav_req)?;
54 Ok(response.or_else(|_| Err(NavigationError::RequestBufferTooSmall)))
55 }
56
57 pub fn run_app(&self, app_id: AppId) -> Result<RunAppResponse, GuiServerError>
58 where
59 P: MessageAllowed<RunApp>,
60 {
61 Ok(self.conn.try_send_blocking_archive(RunApp { app_id })?)
62 }
63
64 pub fn check_user_presence(
65 &self,
66 options: UserPresenceOptions,
67 ) -> Result<Option<UserPresenceResult>, GuiServerError>
68 where
69 P: MessageAllowed<NavigateTo>,
70 {
71 let request = SecurityKeysNavRequest::UserPresence(options);
72 let res = self.navigate_to(SECURITY_KEYS_APP_ID, &request.serialize())?;
73
74 match res {
75 Ok(response) => Ok(UserPresenceResult::from_slice(response.as_slice())),
76 Err(NavigationError::CanceledBySystem) | Err(NavigationError::CanceledByUser) => {
77 Ok(Some(UserPresenceResult::new_cancelled()))
78 }
79 Err(e) => Err(GuiServerError::Navigation(e)),
80 }
81 }
82
83 pub fn invoke_alert(&self, alert: alerts::InvokeAlert) -> Result<alerts::AlertResult, GuiServerError>
84 where
85 P: MessageAllowed<ShowModal>,
86 {
87 let res = self.show_modal(ALERTS_APP_ID, ModalStyle::SlideUpFullscreen, &alert.serialize())?;
88
89 match res {
90 Ok(response) => Ok(alerts::AlertResult::from_slice(response.as_slice())
91 .ok_or(GuiServerError::Navigation(NavigationError::InternalError))?),
92 Err(NavigationError::CanceledBySystem) | Err(NavigationError::CanceledByUser) => {
93 Ok(alerts::AlertResult::Canceled)
94 }
95 Err(e) => Err(GuiServerError::Navigation(e)),
96 }
97 }
98}
99
100impl<P: CheckedPermissions> GuiApi<P> {
101 pub fn navigate_finish(&self, response: Vec<u8>) -> Result<(), GuiServerError>
102 where
103 P: MessageAllowed<FinishResponse>,
104 {
105 let response = FinishResponse { response };
106 Ok(self.conn.try_send_blocking_archive(response)?)
107 }
108
109 pub fn navigate_cancel(&self) -> Result<(), GuiServerError>
110 where
111 P: MessageAllowed<NavigationCancel>,
112 {
113 self.conn.try_send_scalar(NavigationCancel)?;
114 Ok(())
115 }
116
117 pub fn navigate_pending(&self) -> Result<Option<Vec<u8>>, GuiServerError>
118 where
119 P: MessageAllowed<GetPendingNavRequest>,
120 {
121 Ok(self.conn.try_send_blocking_archive(GetPendingNavRequest)?)
122 }
123}