Skip to main content

lingxia_platform/
lib.rs

1//! LingXia Platform
2//!
3//! This crate provides the platform-specific implementation for LingXia.
4
5use std::io::Read;
6
7/// Asset file entry with reader for streaming content
8pub struct AssetFileEntry<'a> {
9    pub path: String,
10    pub reader: Box<dyn Read + 'a>,
11}
12
13/// Device information
14#[derive(Debug, Clone)]
15pub struct DeviceInfo {
16    pub brand: String,
17    pub model: String,
18    pub market_name: String,
19    pub os_name: String,
20    pub os_version: String,
21}
22
23/// Screen information reported in logical pixels (dp/pt) and scale factor
24#[derive(Debug, Clone, serde::Serialize)]
25pub struct ScreenInfo {
26    pub width: f64,
27    pub height: f64,
28    pub scale: f64,
29}
30
31mod banner_background;
32pub mod control_session;
33pub(crate) mod rt;
34pub mod traits;
35
36/// Independent realtime capture contract. Not an `AppRuntime` supertrait.
37#[cfg(feature = "capture-contract")]
38pub mod capture;
39
40#[cfg(target_os = "android")]
41mod android;
42
43#[cfg(any(target_os = "ios", target_os = "macos"))]
44mod apple;
45
46#[cfg(target_env = "ohos")]
47pub mod harmony;
48
49#[cfg(target_os = "windows")]
50pub mod windows;
51
52#[cfg(not(any(
53    target_os = "android",
54    target_os = "ios",
55    target_os = "macos",
56    target_os = "windows",
57    target_env = "ohos"
58)))]
59mod unsupported;
60
61#[cfg(any(target_os = "macos", target_os = "windows"))]
62pub mod desktop;
63
64/// Canonical platform-family label — the single source of truth for "which
65/// OS is this," shared by the WebView bridge config injection
66/// (`lingxia-lxapp`), `lx.host.getBaseInfo().os`, and `lx.getDeviceInfo().osName`
67/// (`lingxia-logic`) so the three can never drift apart. Matches the values
68/// the View-side bridge already exposes via `usePlatform().os`.
69pub fn os_label() -> &'static str {
70    #[cfg(any(target_os = "ios", target_os = "macos"))]
71    {
72        if cfg!(target_os = "macos") {
73            "macOS"
74        } else {
75            "iOS"
76        }
77    }
78    #[cfg(target_os = "android")]
79    {
80        "Android"
81    }
82    #[cfg(target_os = "windows")]
83    {
84        "Windows"
85    }
86    #[cfg(all(target_os = "linux", target_env = "ohos"))]
87    {
88        "Harmony"
89    }
90    #[cfg(not(any(
91        target_os = "ios",
92        target_os = "macos",
93        target_os = "android",
94        target_os = "windows",
95        all(target_os = "linux", target_env = "ohos"),
96    )))]
97    {
98        "unknown"
99    }
100}
101
102/// Local notifications are implemented on every LingXia host. Presence of
103/// `lx.host.notification` also requires the declared yaml capability.
104#[cfg(any(
105    target_os = "macos",
106    target_os = "windows",
107    target_os = "ios",
108    target_os = "android",
109    all(target_os = "linux", target_env = "ohos"),
110))]
111pub fn notification_supported() -> bool {
112    true
113}
114
115/// Desktop banner is a product-drawn overlay, not an OS notification.
116#[cfg(any(target_os = "macos", target_os = "windows"))]
117pub fn banner_supported() -> bool {
118    true
119}
120
121#[cfg(not(any(target_os = "macos", target_os = "windows")))]
122pub fn banner_supported() -> bool {
123    false
124}
125
126/// The product-owned chrome this platform can actually paint a count on.
127///
128/// `lx.host.setBadge` skips unsupported surfaces and returns `false` when
129/// none can be painted.
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
131pub struct BadgeSurfaces {
132    /// Dock (macOS), taskbar (Windows), home-screen icon (iOS, HarmonyOS).
133    pub app_icon: bool,
134    /// Menu-bar (macOS) / notification-area (Windows) status item.
135    pub tray: bool,
136    /// The platform draws the badge itself and only understands a count, so a
137    /// non-numeric value is a parameter error rather than a silent clear.
138    pub numeric_only: bool,
139}
140
141/// Android is deliberately absent: there is no cross-vendor launcher badge.
142/// What a launcher shows comes from active notifications, so a standalone
143/// count is not something the platform can honour — and claiming it, then
144/// no-opping, is what this reports instead of.
145pub fn badge_surfaces() -> BadgeSurfaces {
146    #[cfg(target_os = "macos")]
147    {
148        BadgeSurfaces {
149            app_icon: true,
150            tray: true,
151            numeric_only: false,
152        }
153    }
154    #[cfg(target_os = "ios")]
155    {
156        // The home-screen badge is drawn by the notification system: it takes
157        // a count, and only with notification permission.
158        BadgeSurfaces {
159            app_icon: true,
160            tray: false,
161            numeric_only: true,
162        }
163    }
164    #[cfg(target_os = "windows")]
165    {
166        // Taskbar overlay only. The notify-area icon lives in the host SDK and
167        // would need its own compositing path; claiming it here before that
168        // exists is exactly the lie this type is for.
169        BadgeSurfaces {
170            app_icon: true,
171            tray: false,
172            numeric_only: true,
173        }
174    }
175    #[cfg(target_env = "ohos")]
176    {
177        BadgeSurfaces {
178            app_icon: true,
179            tray: false,
180            numeric_only: true,
181        }
182    }
183    #[cfg(not(any(
184        target_os = "macos",
185        target_os = "ios",
186        target_os = "windows",
187        target_env = "ohos"
188    )))]
189    {
190        BadgeSurfaces::default()
191    }
192}
193
194/// Whether launch-at-startup can actually work on this host, probed at
195/// runtime. macOS builds target 12 but SMAppService needs 13+, so the
196/// `lx.host.autostart` member must not be registered from a compile-time
197/// gate alone — presence is the JS support contract.
198#[cfg(any(target_os = "macos", target_os = "windows"))]
199pub fn autostart_supported() -> bool {
200    #[cfg(target_os = "macos")]
201    {
202        apple::autostart_probe_supported()
203    }
204    #[cfg(target_os = "windows")]
205    {
206        true
207    }
208}
209
210#[cfg(target_os = "android")]
211pub use android::{
212    CachedClass, Platform, get_android_id, get_api_level, get_system_property,
213    has_telephony_feature, init_cached_class, initialize_jni, read_external_storage_text,
214    write_external_storage_text,
215};
216
217pub use control_session::{
218    ControlSessionStopHandler, request_control_session_stop, set_control_session_stop_handler,
219};
220
221#[cfg(any(target_os = "ios", target_os = "macos"))]
222pub use apple::Platform;
223#[cfg(any(target_os = "ios", target_os = "macos"))]
224pub use apple::apply_staged_macos_update;
225
226#[cfg(target_env = "ohos")]
227pub use harmony::Platform;
228
229#[cfg(target_os = "windows")]
230pub use windows::{
231    Platform, WindowsMediaPreviewCancel, WindowsMediaPreviewOpen, WindowsUrlSurfaceWebTag,
232    WindowsVideoCommandDispatcher, apply_staged_windows_update, ensure_toast_activator,
233    install_windows_aside_panel_bridge, register_windows_media_preview_host,
234    register_windows_video_command_dispatcher, remove_toast_registration,
235    replay_windows_exclusive_update_ready, set_toast_activate_handler,
236    set_windows_activate_browser_tab_handler, set_windows_app_exit_handler,
237    set_windows_builtin_browser_downloads_handler, set_windows_capsule_rect_provider,
238    set_windows_close_browser_tab_handler, set_windows_exclusive_update_ready_handler,
239    set_windows_home_first_ready_handler, set_windows_host_appearance_dark,
240    set_windows_host_color_mode_handler, set_windows_layout_plan_handler,
241    set_windows_lxapp_hidden_handler, set_windows_lxapp_main_activation_handler,
242    set_windows_managed_aside_event_handler, set_windows_managed_native_surface_open_handler,
243    set_windows_managed_surface_close_handler, set_windows_managed_surface_visible_handler,
244    set_windows_open_url_handler, set_windows_page_visibility_handler,
245    set_windows_pull_to_refresh_handler, set_windows_shell_pins_handler,
246    set_windows_sidebar_actions_handler, set_windows_surface_closed_handler,
247    set_windows_surface_dispose_handler, set_windows_tray_click_intercept_handler,
248    set_windows_tray_menu_handler, set_windows_ui_update_async_handler,
249    set_windows_ui_update_handler, set_windows_url_surface_handler, sync_windows_ui,
250};
251
252#[cfg(not(any(
253    target_os = "android",
254    target_os = "ios",
255    target_os = "macos",
256    target_os = "windows",
257    target_env = "ohos"
258)))]
259pub use unsupported::Platform;
260
261pub mod error;
262pub use error::*;
263
264pub mod i18n;