1pub use error::*;
4pub use messages::*;
5
6pub mod error;
7pub mod messages;
8
9use server::{CheckedConn, CheckedPermissions, MessageAllowed};
10use xous::{AppId, PID};
11
12pub const SIDELOADED_APPS_DIR: &str = "keyos/sideloaded-apps";
15
16#[macro_export]
17macro_rules! use_api {
18 () => {
19 mod app_manager_permissions {
20 use app_manager::messages::*;
21 #[derive(Clone, Default, server::Permissions)]
22 #[server_name = "os/app-manager"]
23 pub struct AppManagerPermissions;
24 }
25 type AppManagerApi = app_manager::AppManagerApi<app_manager_permissions::AppManagerPermissions>;
26 };
27}
28
29#[derive(Clone, Default)]
30pub struct AppManagerApi<P: CheckedPermissions>(pub(crate) CheckedConn<P>);
31
32impl<P: CheckedPermissions> AppManagerApi<P> {
33 pub fn launch_app_blocking(&self, app_id: &AppId) -> Result<PID, AppManagerError>
34 where
35 P: MessageAllowed<LaunchAppBlocking>,
36 {
37 self.0
38 .try_send_blocking_scalar(LaunchAppBlocking(*app_id))
39 .map_err(|_| AppManagerError::InternalError)?
40 }
41
42 pub fn launch_app(&self, app_id: &AppId) -> Result<(), xous::Error>
43 where
44 P: MessageAllowed<LaunchApp>,
45 {
46 self.0.try_send_scalar(LaunchApp(*app_id))?;
47 Ok(())
48 }
49
50 pub fn refresh_installed_apps(&self) -> Result<(), AppManagerError>
51 where
52 P: MessageAllowed<RefreshInstalledApps>,
53 {
54 self.0.try_send_blocking_scalar(RefreshInstalledApps).map_err(|_| AppManagerError::InternalError)?
55 }
56
57 pub fn refresh_installed_app(&self, app_id: AppId) -> Result<(), AppManagerError>
60 where
61 P: MessageAllowed<RefreshInstalledApp>,
62 {
63 self.0
64 .try_send_blocking_scalar(RefreshInstalledApp(app_id))
65 .map_err(|_| AppManagerError::InternalError)?
66 }
67
68 pub fn app_name_by_app_id(&self, id: &AppId, locale: &str) -> Option<String>
69 where
70 P: MessageAllowed<GetAppName>,
71 {
72 self.0.send_blocking_archive(GetAppName::new_by_app_id(id, locale))
73 }
74
75 pub fn app_name_by_pid(&self, pid: PID, locale: &str) -> Option<String>
76 where
77 P: MessageAllowed<GetAppName>,
78 {
79 self.0.send_blocking_archive(GetAppName::new_by_pid(pid, locale))
80 }
81
82 pub fn get_qr_match_rules(&self) -> Vec<AppQrMatchRules>
83 where
84 P: MessageAllowed<GetQrMatchRules>,
85 {
86 self.0.send_blocking_archive(GetQrMatchRules { app_ids: Vec::new() })
87 }
88
89 pub fn list_apps(&self, locale: &str, filter: AppFilter) -> Vec<InstalledAppInfo>
92 where
93 P: MessageAllowed<ListApps>,
94 {
95 self.0.send_blocking_archive(ListApps { locale: locale.to_string(), filter })
96 }
97
98 pub fn get_app_icon(&self, app_id: &str, variant: IconVariant) -> Option<Vec<u8>>
99 where
100 P: MessageAllowed<GetAppIcon>,
101 {
102 self.0.send_blocking_archive(GetAppIcon { app_id: app_id.to_string(), variant })
103 }
104
105 pub fn set_app_permission_grant(
106 &self,
107 app_id: &str,
108 subgroup: &str,
109 decision: PermissionGrantDecision,
110 ) -> SetAppPermissionGrantResult
111 where
112 P: MessageAllowed<SetAppPermissionGrant>,
113 {
114 self.0.send_blocking_archive(SetAppPermissionGrant {
115 app_id: app_id.to_string(),
116 subgroup: subgroup.to_string(),
117 decision,
118 })
119 }
120
121 pub fn get_permission_request_info(
122 &self,
123 sender_app_id: [u8; 16],
124 server_sid: [u32; 4],
125 message_id: usize,
126 locale: &str,
127 ) -> PermissionRequestInfoResult
128 where
129 P: MessageAllowed<GetPermissionRequestInfo>,
130 {
131 self.0.send_blocking_archive(GetPermissionRequestInfo {
132 sender_app_id,
133 server_sid,
134 message_id,
135 locale: locale.to_string(),
136 })
137 }
138
139 pub fn get_third_party_certificates(&self) -> Vec<ThirdPartyCertificateInfo>
140 where
141 P: MessageAllowed<GetThirdPartyCertificates>,
142 {
143 self.0.send_blocking_archive(GetThirdPartyCertificates)
144 }
145
146 pub fn preview_third_party_certificate(
147 &self,
148 certificate_pem: Vec<u8>,
149 ) -> Result<Result<ThirdPartyCertificateInfo, ThirdPartyCertificateError>, xous::Error>
150 where
151 P: MessageAllowed<PreviewThirdPartyCertificate>,
152 {
153 self.0.try_send_blocking_archive(PreviewThirdPartyCertificate { certificate_pem })
154 }
155
156 pub fn import_third_party_certificate(
157 &self,
158 certificate_pem: Vec<u8>,
159 expected_fingerprint: impl Into<String>,
160 ) -> Result<Result<ThirdPartyCertificateInfo, ThirdPartyCertificateError>, xous::Error>
161 where
162 P: MessageAllowed<ImportThirdPartyCertificate>,
163 {
164 self.0.try_send_blocking_archive(ImportThirdPartyCertificate {
165 certificate_pem,
166 expected_fingerprint: expected_fingerprint.into(),
167 })
168 }
169
170 pub fn remove_third_party_certificate(
171 &self,
172 fingerprint: impl Into<String>,
173 locale: &str,
174 ) -> Result<RemoveThirdPartyCertificateResult, xous::Error>
175 where
176 P: MessageAllowed<RemoveThirdPartyCertificate>,
177 {
178 self.0.try_send_blocking_archive(RemoveThirdPartyCertificate {
179 fingerprint: fingerprint.into(),
180 locale: locale.to_string(),
181 })
182 }
183
184 pub fn remove_app(&self, app_id: &AppId) -> Result<(), xous::Error>
186 where
187 P: MessageAllowed<RemoveApp>,
188 {
189 self.0.try_send_scalar(RemoveApp(*app_id))
190 }
191
192 pub fn install_app_archive(
193 &self,
194 path: impl Into<String>,
195 location: ArchiveLocation,
196 locale: &str,
197 ) -> Result<Result<InstallAppArchiveResult, InstallError>, xous::Error>
198 where
199 P: MessageAllowed<InstallAppArchive>,
200 {
201 self.0.try_send_blocking_archive(InstallAppArchive {
202 path: path.into(),
203 location,
204 locale: locale.to_string(),
205 })
206 }
207
208 pub fn server_subscribe_app_events<S>(&self, context: &mut server::ServerContext<S>)
212 where
213 P: 'static,
214 P: MessageAllowed<SubscribeAppEvents>,
215 S: server::Server + server::ArchiveEventHandler<AppEvent>,
216 {
217 self.0.subscribe_archive_infallible(SubscribeAppEvents, context)
218 }
219}
220
221pub fn decode_app_id_str(id: &str) -> anyhow::Result<AppId> {
222 Ok(AppId(app_manifest::parse_app_id_bytes(id)?))
223}