diff --git a/packages/smtc_windows/lib/src/bridge_generated.dart b/packages/smtc_windows/lib/src/bridge_generated.dart index 3ede9c7..e648551 100644 --- a/packages/smtc_windows/lib/src/bridge_generated.dart +++ b/packages/smtc_windows/lib/src/bridge_generated.dart @@ -1,5 +1,5 @@ // AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.82.1. +// Generated by `flutter_rust_bridge`@ 1.82.6. // ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal, duplicate_import, unused_import, unnecessary_import, prefer_single_quotes, prefer_const_constructors, use_super_parameters, always_use_package_imports, annotate_overrides, invalid_use_of_protected_member, constant_identifier_names, invalid_use_of_internal_member, prefer_is_empty, unnecessary_const import 'dart:convert'; @@ -92,6 +92,7 @@ class MusicMetadata { final String? album; final String? albumArtist; final String? thumbnail; + final Uint8List? thumbnailStream; const MusicMetadata({ this.title, @@ -99,6 +100,7 @@ class MusicMetadata { this.album, this.albumArtist, this.thumbnail, + this.thumbnailStream, }); } @@ -386,7 +388,7 @@ class SmtcWindowsImpl implements SmtcWindows { return _platform.executeStream(FlutterRustBridgeTask( callFfi: (port_) => _platform.inner.wire_smtc_button_press_event(port_, arg0), parseSuccessData: _wire2api_String, - parseErrorData: null, + parseErrorData: _wire2api_FrbAnyhowException, constMeta: kSmtcButtonPressEventConstMeta, argValues: [ internal @@ -407,7 +409,7 @@ class SmtcWindowsImpl implements SmtcWindows { return _platform.executeStream(FlutterRustBridgeTask( callFfi: (port_) => _platform.inner.wire_smtc_position_change_request_event(port_, arg0), parseSuccessData: _wire2api_i64, - parseErrorData: null, + parseErrorData: _wire2api_FrbAnyhowException, constMeta: kSmtcPositionChangeRequestEventConstMeta, argValues: [ internal @@ -428,7 +430,7 @@ class SmtcWindowsImpl implements SmtcWindows { return _platform.executeStream(FlutterRustBridgeTask( callFfi: (port_) => _platform.inner.wire_smtc_shuffle_request_event(port_, arg0), parseSuccessData: _wire2api_bool, - parseErrorData: null, + parseErrorData: _wire2api_FrbAnyhowException, constMeta: kSmtcShuffleRequestEventConstMeta, argValues: [ internal @@ -449,7 +451,7 @@ class SmtcWindowsImpl implements SmtcWindows { return _platform.executeStream(FlutterRustBridgeTask( callFfi: (port_) => _platform.inner.wire_smtc_repeat_mode_request_event(port_, arg0), parseSuccessData: _wire2api_String, - parseErrorData: null, + parseErrorData: _wire2api_FrbAnyhowException, constMeta: kSmtcRepeatModeRequestEventConstMeta, argValues: [ internal @@ -599,6 +601,11 @@ class SmtcWindowsPlatform extends FlutterRustBridgeBase { return raw == null ? ffi.nullptr : api2wire_box_autoadd_i64(raw); } + @protected + ffi.Pointer api2wire_opt_uint_8_list(Uint8List? raw) { + return raw == null ? ffi.nullptr : api2wire_uint_8_list(raw); + } + @protected ffi.Pointer api2wire_uint_8_list(Uint8List raw) { final ans = inner.new_uint_8_list_0(raw.length); @@ -633,6 +640,7 @@ class SmtcWindowsPlatform extends FlutterRustBridgeBase { wireObj.album = api2wire_opt_String(apiObj.album); wireObj.album_artist = api2wire_opt_String(apiObj.albumArtist); wireObj.thumbnail = api2wire_opt_String(apiObj.thumbnail); + wireObj.thumbnail_stream = api2wire_opt_uint_8_list(apiObj.thumbnailStream); } void _api_fill_to_wire_playback_timeline(PlaybackTimeline apiObj, wire_PlaybackTimeline wireObj) { @@ -1063,6 +1071,8 @@ final class wire_MusicMetadata extends ffi.Struct { external ffi.Pointer album_artist; external ffi.Pointer thumbnail; + + external ffi.Pointer thumbnail_stream; } final class wire_PlaybackTimeline extends ffi.Struct { diff --git a/packages/smtc_windows/native/src/bridge_generated.io.rs b/packages/smtc_windows/native/src/bridge_generated.io.rs new file mode 100644 index 0000000..c91a000 --- /dev/null +++ b/packages/smtc_windows/native/src/bridge_generated.io.rs @@ -0,0 +1,373 @@ +use super::*; +// Section: wire functions + +#[no_mangle] +pub extern "C" fn wire_smtc_new(enabled: *mut bool) -> support::WireSyncReturn { + wire_smtc_new_impl(enabled) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_config( + port_: i64, + internal: wire_SmtcInternal, + config: *mut wire_SMTCConfig, +) { + wire_smtc_update_config_impl(port_, internal, config) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_metadata( + port_: i64, + internal: wire_SmtcInternal, + metadata: *mut wire_MusicMetadata, +) { + wire_smtc_update_metadata_impl(port_, internal, metadata) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_clear_metadata(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_clear_metadata_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_timeline( + port_: i64, + internal: wire_SmtcInternal, + timeline: *mut wire_PlaybackTimeline, +) { + wire_smtc_update_timeline_impl(port_, internal, timeline) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_playback_status( + port_: i64, + internal: wire_SmtcInternal, + status: i32, +) { + wire_smtc_update_playback_status_impl(port_, internal, status) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_shuffle(port_: i64, internal: wire_SmtcInternal, shuffle: bool) { + wire_smtc_update_shuffle_impl(port_, internal, shuffle) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_update_repeat_mode( + port_: i64, + internal: wire_SmtcInternal, + repeat_mode: *mut wire_uint_8_list, +) { + wire_smtc_update_repeat_mode_impl(port_, internal, repeat_mode) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_enable_smtc(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_enable_smtc_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_disable_smtc(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_disable_smtc_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_button_press_event(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_button_press_event_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_position_change_request_event(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_position_change_request_event_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_shuffle_request_event(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_shuffle_request_event_impl(port_, internal) +} + +#[no_mangle] +pub extern "C" fn wire_smtc_repeat_mode_request_event(port_: i64, internal: wire_SmtcInternal) { + wire_smtc_repeat_mode_request_event_impl(port_, internal) +} + +// Section: allocate functions + +#[no_mangle] +pub extern "C" fn new_SmtcInternal() -> wire_SmtcInternal { + wire_SmtcInternal::new_with_null_ptr() +} + +#[no_mangle] +pub extern "C" fn new_box_autoadd_bool_0(value: bool) -> *mut bool { + support::new_leak_box_ptr(value) +} + +#[no_mangle] +pub extern "C" fn new_box_autoadd_i64_0(value: i64) -> *mut i64 { + support::new_leak_box_ptr(value) +} + +#[no_mangle] +pub extern "C" fn new_box_autoadd_music_metadata_0() -> *mut wire_MusicMetadata { + support::new_leak_box_ptr(wire_MusicMetadata::new_with_null_ptr()) +} + +#[no_mangle] +pub extern "C" fn new_box_autoadd_playback_timeline_0() -> *mut wire_PlaybackTimeline { + support::new_leak_box_ptr(wire_PlaybackTimeline::new_with_null_ptr()) +} + +#[no_mangle] +pub extern "C" fn new_box_autoadd_smtc_config_0() -> *mut wire_SMTCConfig { + support::new_leak_box_ptr(wire_SMTCConfig::new_with_null_ptr()) +} + +#[no_mangle] +pub extern "C" fn new_uint_8_list_0(len: i32) -> *mut wire_uint_8_list { + let ans = wire_uint_8_list { + ptr: support::new_leak_vec_ptr(Default::default(), len), + len, + }; + support::new_leak_box_ptr(ans) +} + +// Section: related functions + +#[no_mangle] +pub extern "C" fn drop_opaque_SmtcInternal(ptr: *const c_void) { + unsafe { + Arc::::decrement_strong_count(ptr as _); + } +} + +#[no_mangle] +pub extern "C" fn share_opaque_SmtcInternal(ptr: *const c_void) -> *const c_void { + unsafe { + Arc::::increment_strong_count(ptr as _); + ptr + } +} + +// Section: impl Wire2Api + +impl Wire2Api> for wire_SmtcInternal { + fn wire2api(self) -> RustOpaque { + unsafe { support::opaque_from_dart(self.ptr as _) } + } +} +impl Wire2Api for *mut wire_uint_8_list { + fn wire2api(self) -> String { + let vec: Vec = self.wire2api(); + String::from_utf8_lossy(&vec).into_owned() + } +} + +impl Wire2Api for *mut bool { + fn wire2api(self) -> bool { + unsafe { *support::box_from_leak_ptr(self) } + } +} +impl Wire2Api for *mut i64 { + fn wire2api(self) -> i64 { + unsafe { *support::box_from_leak_ptr(self) } + } +} +impl Wire2Api for *mut wire_MusicMetadata { + fn wire2api(self) -> MusicMetadata { + let wrap = unsafe { support::box_from_leak_ptr(self) }; + Wire2Api::::wire2api(*wrap).into() + } +} +impl Wire2Api for *mut wire_PlaybackTimeline { + fn wire2api(self) -> PlaybackTimeline { + let wrap = unsafe { support::box_from_leak_ptr(self) }; + Wire2Api::::wire2api(*wrap).into() + } +} +impl Wire2Api for *mut wire_SMTCConfig { + fn wire2api(self) -> SMTCConfig { + let wrap = unsafe { support::box_from_leak_ptr(self) }; + Wire2Api::::wire2api(*wrap).into() + } +} + +impl Wire2Api for wire_MusicMetadata { + fn wire2api(self) -> MusicMetadata { + MusicMetadata { + title: self.title.wire2api(), + artist: self.artist.wire2api(), + album: self.album.wire2api(), + album_artist: self.album_artist.wire2api(), + thumbnail: self.thumbnail.wire2api(), + thumbnail_stream: self.thumbnail_stream.wire2api(), + } + } +} + +impl Wire2Api for wire_PlaybackTimeline { + fn wire2api(self) -> PlaybackTimeline { + PlaybackTimeline { + start_time_ms: self.start_time_ms.wire2api(), + end_time_ms: self.end_time_ms.wire2api(), + position_ms: self.position_ms.wire2api(), + min_seek_time_ms: self.min_seek_time_ms.wire2api(), + max_seek_time_ms: self.max_seek_time_ms.wire2api(), + } + } +} +impl Wire2Api for wire_SMTCConfig { + fn wire2api(self) -> SMTCConfig { + SMTCConfig { + play_enabled: self.play_enabled.wire2api(), + pause_enabled: self.pause_enabled.wire2api(), + stop_enabled: self.stop_enabled.wire2api(), + next_enabled: self.next_enabled.wire2api(), + prev_enabled: self.prev_enabled.wire2api(), + fast_forward_enabled: self.fast_forward_enabled.wire2api(), + rewind_enabled: self.rewind_enabled.wire2api(), + } + } +} + +impl Wire2Api> for *mut wire_uint_8_list { + fn wire2api(self) -> Vec { + unsafe { + let wrap = support::box_from_leak_ptr(self); + support::vec_from_leak_ptr(wrap.ptr, wrap.len) + } + } +} +// Section: wire structs + +#[repr(C)] +#[derive(Clone)] +pub struct wire_SmtcInternal { + ptr: *const core::ffi::c_void, +} + +#[repr(C)] +#[derive(Clone)] +pub struct wire_MusicMetadata { + title: *mut wire_uint_8_list, + artist: *mut wire_uint_8_list, + album: *mut wire_uint_8_list, + album_artist: *mut wire_uint_8_list, + thumbnail: *mut wire_uint_8_list, + thumbnail_stream: *mut wire_uint_8_list, +} + +#[repr(C)] +#[derive(Clone)] +pub struct wire_PlaybackTimeline { + start_time_ms: i64, + end_time_ms: i64, + position_ms: i64, + min_seek_time_ms: *mut i64, + max_seek_time_ms: *mut i64, +} + +#[repr(C)] +#[derive(Clone)] +pub struct wire_SMTCConfig { + play_enabled: bool, + pause_enabled: bool, + stop_enabled: bool, + next_enabled: bool, + prev_enabled: bool, + fast_forward_enabled: bool, + rewind_enabled: bool, +} + +#[repr(C)] +#[derive(Clone)] +pub struct wire_uint_8_list { + ptr: *mut u8, + len: i32, +} + +// Section: impl NewWithNullPtr + +pub trait NewWithNullPtr { + fn new_with_null_ptr() -> Self; +} + +impl NewWithNullPtr for *mut T { + fn new_with_null_ptr() -> Self { + std::ptr::null_mut() + } +} + +impl NewWithNullPtr for wire_SmtcInternal { + fn new_with_null_ptr() -> Self { + Self { + ptr: core::ptr::null(), + } + } +} + +impl NewWithNullPtr for wire_MusicMetadata { + fn new_with_null_ptr() -> Self { + Self { + title: core::ptr::null_mut(), + artist: core::ptr::null_mut(), + album: core::ptr::null_mut(), + album_artist: core::ptr::null_mut(), + thumbnail: core::ptr::null_mut(), + thumbnail_stream: core::ptr::null_mut(), + } + } +} + +impl Default for wire_MusicMetadata { + fn default() -> Self { + Self::new_with_null_ptr() + } +} + +impl NewWithNullPtr for wire_PlaybackTimeline { + fn new_with_null_ptr() -> Self { + Self { + start_time_ms: Default::default(), + end_time_ms: Default::default(), + position_ms: Default::default(), + min_seek_time_ms: core::ptr::null_mut(), + max_seek_time_ms: core::ptr::null_mut(), + } + } +} + +impl Default for wire_PlaybackTimeline { + fn default() -> Self { + Self::new_with_null_ptr() + } +} + +impl NewWithNullPtr for wire_SMTCConfig { + fn new_with_null_ptr() -> Self { + Self { + play_enabled: Default::default(), + pause_enabled: Default::default(), + stop_enabled: Default::default(), + next_enabled: Default::default(), + prev_enabled: Default::default(), + fast_forward_enabled: Default::default(), + rewind_enabled: Default::default(), + } + } +} + +impl Default for wire_SMTCConfig { + fn default() -> Self { + Self::new_with_null_ptr() + } +} + +// Section: sync execution mode utility + +#[no_mangle] +pub extern "C" fn free_WireSyncReturn(ptr: support::WireSyncReturn) { + unsafe { + let _ = support::box_from_leak_ptr(ptr); + }; +} diff --git a/packages/smtc_windows/native/src/bridge_generated.rs b/packages/smtc_windows/native/src/bridge_generated.rs index 779cc1e..9a77aa5 100644 --- a/packages/smtc_windows/native/src/bridge_generated.rs +++ b/packages/smtc_windows/native/src/bridge_generated.rs @@ -9,7 +9,7 @@ clippy::too_many_arguments )] // AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.82.1. +// Generated by `flutter_rust_bridge`@ 1.82.6. use crate::api::*; use core::panic::UnwindSafe; @@ -554,6 +554,7 @@ mod io { album: self.album.wire2api(), album_artist: self.album_artist.wire2api(), thumbnail: self.thumbnail.wire2api(), + thumbnail_stream: self.thumbnail_stream.wire2api(), } } } @@ -607,6 +608,7 @@ mod io { album: *mut wire_uint_8_list, album_artist: *mut wire_uint_8_list, thumbnail: *mut wire_uint_8_list, + thumbnail_stream: *mut wire_uint_8_list, } #[repr(C)] @@ -666,6 +668,7 @@ mod io { album: core::ptr::null_mut(), album_artist: core::ptr::null_mut(), thumbnail: core::ptr::null_mut(), + thumbnail_stream: core::ptr::null_mut(), } } } @@ -724,4 +727,4 @@ mod io { } } #[cfg(not(target_family = "wasm"))] -pub use io::*; +pub use self::io::*; diff --git a/packages/smtc_windows/native/src/internal/metadata.rs b/packages/smtc_windows/native/src/internal/metadata.rs index 838ae58..b92de3f 100644 --- a/packages/smtc_windows/native/src/internal/metadata.rs +++ b/packages/smtc_windows/native/src/internal/metadata.rs @@ -7,6 +7,7 @@ pub struct MusicMetadata { pub album: Option, pub album_artist: Option, pub thumbnail: Option, + pub thumbnail_stream: Option>, } impl MusicMetadata { diff --git a/packages/smtc_windows/native/src/internal/smtc_internal.rs b/packages/smtc_windows/native/src/internal/smtc_internal.rs index 84e2ac5..cba75db 100644 --- a/packages/smtc_windows/native/src/internal/smtc_internal.rs +++ b/packages/smtc_windows/native/src/internal/smtc_internal.rs @@ -1,4 +1,5 @@ use flutter_rust_bridge::StreamSink; +use windows::Storage::Streams::{DataWriter, InMemoryRandomAccessStream}; use windows::{ Foundation::{self, TypedEventHandler}, Media::{ @@ -73,8 +74,20 @@ impl SMTCInternal { RandomAccessStreamReference::CreateFromUri(&uri).unwrap() }); + let thumbnail_stream = metadata.thumbnail_stream.map(|s| { + let stream = InMemoryRandomAccessStream::new().unwrap(); + let writer = DataWriter::CreateDataWriter(&stream).unwrap(); + writer.WriteBytes(&s).unwrap(); + writer.StoreAsync().unwrap().get().unwrap(); + writer.FlushAsync().unwrap().get().unwrap(); + writer.DetachStream().unwrap(); + RandomAccessStreamReference::CreateFromStream(&stream).unwrap() + }); + if let Some(thumbnail) = thumbnail { updater.SetThumbnail(thumbnail)?; + } else if let Some(thumbnail_stream) = thumbnail_stream { + updater.SetThumbnail(&thumbnail_stream)?; } updater.Update()?; diff --git a/packages/smtc_windows/windows/smtc_windows.dll b/packages/smtc_windows/windows/smtc_windows.dll index f2541ba..702b4b5 100644 Binary files a/packages/smtc_windows/windows/smtc_windows.dll and b/packages/smtc_windows/windows/smtc_windows.dll differ diff --git a/scripts/regenerate_bridge.ps1 b/scripts/regenerate_bridge.ps1 new file mode 100644 index 0000000..38ff3e4 --- /dev/null +++ b/scripts/regenerate_bridge.ps1 @@ -0,0 +1,2 @@ +cargo install flutter_rust_bridge_codegen@1.80.1 +flutter_rust_bridge_codegen --rust-input ..\packages\smtc_windows\native\src\api.rs --dart-output ..\packages\smtc_windows\lib\src\bridge_generated.dart -v \ No newline at end of file