1use std::io::Read;
2use std::path::{Path, PathBuf};
3
4use crate::AssetFileEntry;
5use crate::error::PlatformError;
6
7use super::device::{Device, DeviceHardware};
8use super::file::FileService;
9use super::location::Location;
10use super::media_interaction::{MediaInteraction, MediaKind};
11use super::media_runtime::MediaRuntime;
12use super::network::Network;
13use super::secure_store::SecureStore;
14use super::share::ShareService;
15use super::ui::{SurfacePresenter, UIUpdate, UserFeedback};
16use super::update::UpdateService;
17use super::wifi::Wifi;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum AnimationType {
21 None = 0,
22 Forward = 1,
23 Backward = 2,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
27pub enum LxAppOpenMode {
28 #[default]
29 Normal = 0,
30 Panel = 1,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum OpenUrlTarget {
35 External = 0,
36 SelfTarget = 1,
37 NewBrowserTab = 2,
39}
40
41impl OpenUrlTarget {
42 pub fn parse(raw: Option<&str>) -> Self {
43 match raw.map(|v| v.trim().to_ascii_lowercase()) {
44 Some(v) if v == "self" => Self::SelfTarget,
45 Some(v) if v == "new_browser_tab" => Self::NewBrowserTab,
46 Some(v) if v == "external" => Self::External,
47 Some(v) => {
48 log::warn!("Invalid openURL target='{}', fallback to external", v);
49 Self::External
50 }
51 None => Self::External,
52 }
53 }
54}
55
56#[derive(Debug, Clone)]
57pub struct OpenUrlRequest {
58 pub owner_appid: String,
59 pub owner_session_id: u64,
60 pub url: String,
61 pub target: OpenUrlTarget,
62}
63
64impl From<i32> for AnimationType {
65 fn from(value: i32) -> Self {
66 match value {
67 1 => AnimationType::Forward,
68 2 => AnimationType::Backward,
69 _ => AnimationType::None,
70 }
71 }
72}
73
74pub trait AppRuntime:
75 Send
76 + Sync
77 + MediaInteraction
78 + MediaRuntime
79 + Network
80 + SurfacePresenter
81 + Device
82 + DeviceHardware
83 + SecureStore
84 + ShareService
85 + FileService
86 + Location
87 + UIUpdate
88 + UpdateService
89 + UserFeedback
90 + Wifi
91 + 'static
92{
93 fn read_asset<'a>(&'a self, path: &str) -> Result<Box<dyn Read + 'a>, PlatformError>;
95
96 fn asset_dir_iter<'a>(
98 &'a self,
99 asset_dir: &str,
100 ) -> Box<dyn Iterator<Item = Result<AssetFileEntry<'a>, PlatformError>> + 'a>;
101
102 fn app_data_dir(&self) -> PathBuf;
104
105 fn app_cache_dir(&self) -> PathBuf;
107
108 fn get_app_identifier(&self) -> Result<String, PlatformError>;
110
111 fn copy_album_media_to_file(
113 &self,
114 uri: &str,
115 dest_path: &Path,
116 kind: MediaKind,
117 ) -> Result<(), PlatformError> {
118 MediaRuntime::copy_album_media_to_file(self, uri, dest_path, kind)
119 }
120
121 fn get_system_locale(&self) -> &str;
123
124 fn show_lxapp(
126 &self,
127 appid: String,
128 path: String,
129 session_id: u64,
130 open_mode: LxAppOpenMode,
131 panel_id: String,
132 ) -> Result<(), PlatformError>;
133
134 fn hide_lxapp(&self, appid: String, session_id: u64) -> Result<(), PlatformError>;
136
137 fn exit(&self) -> Result<(), PlatformError>;
139
140 fn set_tray_badge(&self, _text: &str) -> Result<(), PlatformError> {
147 Ok(())
148 }
149
150 fn set_tray_icon(&self, _icon: &str) -> Result<(), PlatformError> {
152 Ok(())
153 }
154
155 fn set_tray_title(&self, _text: &str) -> Result<(), PlatformError> {
157 Ok(())
158 }
159
160 fn set_app_badge(&self, _text: &str) -> Result<(), PlatformError> {
163 Ok(())
164 }
165
166 fn set_tray_menu(&self, _items_json: &str) -> Result<(), PlatformError> {
170 Ok(())
171 }
172
173 fn set_tray_visible(&self, _visible: bool) -> Result<(), PlatformError> {
175 Ok(())
176 }
177
178 fn set_tray_click_intercept(&self, _intercept: bool) -> Result<(), PlatformError> {
182 Ok(())
183 }
184
185 fn navigate(
187 &self,
188 appid: String,
189 path: String,
190 animation_type: AnimationType,
191 ) -> Result<(), PlatformError>;
192
193 fn open_url(&self, req: OpenUrlRequest) -> Result<(), PlatformError>;
195
196 fn get_capsule_rect(
199 &self,
200 ) -> impl std::future::Future<Output = Result<String, PlatformError>> + Send;
201}
202
203#[cfg(test)]
204mod tests {
205 use super::OpenUrlTarget;
206
207 #[test]
208 fn parse_supports_new_browser_tab() {
209 assert_eq!(
210 OpenUrlTarget::parse(Some("new_browser_tab")),
211 OpenUrlTarget::NewBrowserTab
212 );
213 }
214
215 #[test]
216 fn parse_unknown_falls_back_to_external() {
217 assert_eq!(
218 OpenUrlTarget::parse(Some("foobar")),
219 OpenUrlTarget::External
220 );
221 }
222}