mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-21 06:52:18 +02:00
fix(android): preserve remote SAF descriptors for audio and artwork
This commit is contained in:
1 parent
b767bd16d8
commit
bbe2caa754
32 files changed
+2290
-22
No files matched your search
@@ -14,8 +14,8 @@ pub struct DescriptorLibraryMetadata {
|
||||
}
|
||||
|
||||
/// The caller keeps the descriptor open until this synchronous read returns.
|
||||
/// Reopening its descriptor path preserves SAF access instead of resolving a
|
||||
/// protected /storage or /mnt/media_rw path and copying the entire audio file.
|
||||
/// Duplicating its descriptor preserves SAF access, including single-open
|
||||
/// AppFuse proxies, without resolving a protected path or copying the audio.
|
||||
#[uniffi::export]
|
||||
pub fn read_library_metadata_from_descriptor(
|
||||
descriptor: i32,
|
||||
|
||||
@@ -301,6 +301,29 @@ pub(crate) fn check_lease(lease: Option<&RequestLease>) -> Result<(), String> {
|
||||
}
|
||||
|
||||
pub(crate) fn open_audio_file(path: &str) -> Result<File, String> {
|
||||
#[cfg(unix)]
|
||||
if let Some(descriptor) = path
|
||||
.strip_prefix("/proc/self/fd/")
|
||||
.or_else(|| path.strip_prefix("/dev/fd/"))
|
||||
{
|
||||
use std::os::fd::BorrowedFd;
|
||||
let descriptor = descriptor.parse::<i32>().map_err(|e| e.to_string())?;
|
||||
if descriptor < 0 {
|
||||
return Err("invalid audio descriptor".into());
|
||||
}
|
||||
// The native caller retains this lease for the synchronous operation.
|
||||
// Reopening /proc/self/fd issues FUSE_OPEN, which Android AppFuse
|
||||
// explicitly rejects for an already-open proxy. Duplicate instead.
|
||||
#[allow(unsafe_code)] // Native owner retains the descriptor during this call.
|
||||
let owned = unsafe { BorrowedFd::borrow_raw(descriptor) }
|
||||
.try_clone_to_owned()
|
||||
.map_err(|e| e.to_string())?;
|
||||
let file = File::from(owned);
|
||||
if !file.metadata().map_err(|e| e.to_string())?.is_file() {
|
||||
return Err("audio tags require a regular file".into());
|
||||
}
|
||||
return Ok(file);
|
||||
}
|
||||
let mut options = OpenOptions::new();
|
||||
options.read(true);
|
||||
#[cfg(unix)]
|
||||
|
||||
Reference in new issue
Block a user