Skip to main content

fractal/components/camera/linux/
mod.rs

1use std::time::Duration;
2
3use ashpd::desktop::camera;
4use gtk::prelude::*;
5use tokio::time::timeout;
6use tracing::error;
7
8mod viewfinder;
9
10use self::viewfinder::LinuxCameraViewfinder;
11use super::{CameraExt, CameraViewfinder};
12use crate::spawn_tokio;
13
14/// Camera API under Linux.
15#[derive(Debug)]
16pub(crate) struct LinuxCamera;
17
18impl CameraExt for LinuxCamera {
19    async fn has_cameras() -> bool {
20        let fut = async move {
21            let camera = match camera::Camera::new().await {
22                Ok(camera) => camera,
23                Err(error) => {
24                    error!("Could not create instance of camera proxy: {error}");
25                    return false;
26                }
27            };
28
29            match camera.is_present().await {
30                Ok(is_present) => is_present,
31                Err(error) => {
32                    error!("Could not check whether system has cameras: {error}");
33                    false
34                }
35            }
36        };
37        let handle = spawn_tokio!(async move { timeout(Duration::from_secs(1), fut).await });
38
39        if let Ok(is_present) = handle.await.expect("task was not aborted") {
40            is_present
41        } else {
42            error!("Could not check whether system has cameras: request timed out");
43            false
44        }
45    }
46
47    async fn viewfinder() -> Option<CameraViewfinder> {
48        LinuxCameraViewfinder::new().await.and_upcast()
49    }
50}