tauri-plugin-deeprespond-im 1.0.0-alpha

深应智能 IM 的 Tauri 插件:本地存储、安全存储、窗口间的锁与消息、系统事件、通知、角标、文件
//! 媒体设备的权限(《2.功能概述文档》第 10 节):通话和语音消息在 WebView 中使用摄像头和麦克风。
//! - Windows:WebView2 默认对每个页面来源弹出自己的授权提示;插件对本应用自己的页面(tauri.localhost)自动允许摄像头和麦克风,
//!   系统设置中“允许桌面应用访问摄像头/麦克风”仍由用户决定。
//! - macOS:WKWebView 的界面代理由 wry 持有,首版沿用 WebKit 的默认行为(第一次使用时询问)。
//! - Linux:WebKitGTK 的请求由 wry 处理;首版不支持音视频。

use tauri::Runtime;

#[allow(unused_variables)]
pub fn allow_own_media<R: Runtime>(webview: &tauri::Webview<R>) {
    #[cfg(target_os = "windows")]
    {
        let _ = webview.with_webview(|platform| windows_impl::register(&platform));
    }
}

#[cfg(target_os = "windows")]
mod windows_impl {
    use webview2_com::Microsoft::Web::WebView2::Win32::{
        COREWEBVIEW2_PERMISSION_KIND, COREWEBVIEW2_PERMISSION_KIND_CAMERA, COREWEBVIEW2_PERMISSION_KIND_MICROPHONE, COREWEBVIEW2_PERMISSION_STATE_ALLOW,
    };
    use webview2_com::PermissionRequestedEventHandler;

    /// 本应用自己的页面(Tauri 在 Windows 上的来源为 http(s)://tauri.localhost)。
    pub fn own_origin(uri: &str) -> bool {
        ["http://tauri.localhost", "https://tauri.localhost"].iter().any(|o| uri == *o || uri.starts_with(&format!("{o}/")))
    }

    pub fn register(platform: &tauri::webview::PlatformWebview) {
        unsafe {
            let Ok(core) = platform.controller().CoreWebView2() else { return };
            let handler = PermissionRequestedEventHandler::create(Box::new(|_, args| {
                let Some(args) = args else { return Ok(()) };
                let mut kind = COREWEBVIEW2_PERMISSION_KIND::default();
                args.PermissionKind(&mut kind)?;
                let mut uri = windows::core::PWSTR::null();
                args.Uri(&mut uri)?;
                let uri = webview2_com::take_pwstr(uri);
                if own_origin(&uri) && (kind == COREWEBVIEW2_PERMISSION_KIND_CAMERA || kind == COREWEBVIEW2_PERMISSION_KIND_MICROPHONE) {
                    args.SetState(COREWEBVIEW2_PERMISSION_STATE_ALLOW)?;
                }
                Ok(())
            }));
            let mut token = 0i64;
            let _ = core.add_PermissionRequested(&handler, &mut token);
        }
    }
}