1use num_traits::{FromPrimitive, ToPrimitive};
5use server::{rkyv_with::WithAppId, AsScalar, FromScalar};
6use xous::{AppId, PID};
7
8use crate::error::{AppManagerError, LaunchError};
9
10#[derive(Debug, server::Message)]
11#[response(Result<PID, AppManagerError>)]
12pub struct LaunchAppBlocking(pub AppId);
13
14#[derive(Debug, server::Message)]
15#[response(Result<(), AppManagerError>)]
16pub struct RefreshInstalledApps;
17
18impl AsScalar<3> for AppManagerError {
19 fn as_scalar(&self) -> [u32; 3] { [self.to_u32().unwrap(), 0, 0] }
20}
21
22impl FromScalar<3> for AppManagerError {
23 fn from_scalar([e, ..]: [u32; 3]) -> Self {
24 AppManagerError::from_u32(e).unwrap_or(AppManagerError::InternalError)
25 }
26}
27
28#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
29#[event(AppEvent)]
30pub struct SubscribeAppEvents;
31
32#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
33pub enum AppEvent {
34 AppLaunched {
35 #[rkyv(with = WithAppId)]
36 app_id: AppId,
37 pid: PID,
38 launched_by: PID,
39 },
40
41 AppCrashed {
42 #[rkyv(with = WithAppId)]
43 app_id: AppId,
44 pid: PID,
45 launched_by: PID,
46 exit_code: u32,
47 panic_message: Option<String>,
48 },
49
50 LaunchError {
51 #[rkyv(with = WithAppId)]
52 app_id: AppId,
53 error: LaunchError,
54 },
55}
56
57#[derive(Debug, server::Message)]
58pub struct LaunchApp(pub AppId);
59#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
60pub struct AppQrMatchRules {
61 #[rkyv(with = WithAppId)]
62 pub id: AppId,
63 pub rules_json: Vec<u8>,
64}
65
66#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
67pub struct InstalledAppPermissionGroup {
68 pub server: String,
69 pub messages: Vec<String>,
70}
71
72#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
73pub struct InstalledAppInfo {
74 pub app_id: String,
75 pub name: String,
76 pub bundled_icon_path: Option<String>,
80 pub publisher: String,
81 pub can_launch: bool,
82 pub can_remove: bool,
83 pub version: String,
84 pub size_bytes: u64,
85 pub description: String,
86 pub permissions: Vec<InstalledAppPermissionGroup>,
87}
88
89#[derive(
90 Debug, Clone, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize,
91)]
92pub struct ThirdPartyCertificateInfo {
93 pub name: String,
94 pub company: String,
95 pub contact_email: String,
96 pub support_url: String,
97 pub public_key: String,
98 #[serde(default)]
99 pub not_before_unix_seconds: Option<u64>,
100 #[serde(default)]
101 pub not_after_unix_seconds: Option<u64>,
102 pub serial_number: String,
103 pub issuer: String,
104 pub subject: String,
105 pub basic_constraints: String,
106 pub key_usage: String,
107 pub extended_key_usage: String,
108}
109
110#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
111pub enum ImportThirdPartyCertificateResult {
112 Imported(ThirdPartyCertificateInfo),
113 Invalid,
114}
115
116#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
117pub enum RemoveThirdPartyCertificateResult {
118 Removed,
119 NotFound,
120 AppRequiresKey(String),
121 InternalError,
122}
123
124#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
125pub enum RemoveInstalledAppResult {
126 Removed,
127 NotFound,
128 NotSideloaded,
129 Running,
130 InternalError,
131}
132
133#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
134#[response(Option<String>)]
135pub enum GetAppName {
136 ByAppId {
137 #[rkyv(with = WithAppId)]
138 id: AppId,
139 locale: String,
140 },
141
142 ByPid {
143 pid: PID,
144 locale: String,
145 },
146}
147
148impl GetAppName {
149 pub fn new_by_app_id(id: &AppId, locale: &str) -> Self {
150 Self::ByAppId { id: *id, locale: locale.to_string() }
151 }
152
153 pub fn new_by_pid(pid: PID, locale: &str) -> Self { Self::ByPid { pid, locale: locale.to_string() } }
154}
155
156#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
157#[response(Vec<AppQrMatchRules>)]
158pub struct GetQrMatchRules;
159
160#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
162pub struct AppEntry {
163 pub app_id: String,
164 pub name: String,
165 pub is_flux: bool,
167}
168
169impl AppEntry {
170 pub fn new(app_id: &str, name: &str, is_flux: bool) -> Self {
171 AppEntry { app_id: app_id.to_string(), name: name.to_string(), is_flux }
172 }
173}
174
175#[derive(Debug, Clone, Default, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
178pub struct AppFilter {
179 pub is_flux: Option<bool>,
180}
181
182impl AppFilter {
183 pub fn flux_only() -> Self { Self { is_flux: Some(true) } }
185
186 pub fn standard_only() -> Self { Self { is_flux: Some(false) } }
188}
189
190#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
191#[response(Vec<AppEntry>)]
192pub struct ListApps {
193 pub locale: String,
194 pub filter: AppFilter,
195}
196
197#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
198#[response(Vec<InstalledAppInfo>)]
199pub struct GetInstalledApps {
200 pub locale: String,
201}
202
203#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
207#[response(Option<Vec<u8>>)]
208pub struct GetAppIcon {
209 pub app_id: String,
210}
211
212#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
213#[response(Vec<ThirdPartyCertificateInfo>)]
214pub struct GetThirdPartyCertificates;
215
216#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
217#[response(ImportThirdPartyCertificateResult)]
218pub struct ImportThirdPartyCertificate {
219 pub certificate_pem: Vec<u8>,
220}
221
222#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
223#[response(RemoveThirdPartyCertificateResult)]
224pub struct RemoveThirdPartyCertificate {
225 pub public_key: String,
226 pub locale: String,
227}
228
229#[derive(Debug, Clone, server::Message, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
230#[response(RemoveInstalledAppResult)]
231pub struct RemoveInstalledApp {
232 #[rkyv(with = WithAppId)]
233 pub app_id: AppId,
234}