Commit Graph
366 Commits
Author SHA1 Message Date
zarzet 92adce43ef refactor(native): share errorJson and retire Go-era names in native comments
MainActivitySafIo and SafDownloadHandler each defined an identical
errorJson. Keep one internal top-level function in MainActivitySafIo
and drop the private copy. errorJson, isMediaStoreUri, extFromFileName
and extFromMimeType never used their MainActivity receiver, so they
become plain top-level functions; call sites are unchanged.

Rust is the only backend. Rename the iOS invokeGoMethod, which
dispatches the OS-owned channel methods, to invokeOsMethod, and reword
the comments that still described Go calls, the Go progress stream, the
Go metadata reader or a "native migration boundary" so they describe
the current backend. Channel method names and reply keys are unchanged.
2026-10-18 23:01:04 +07:00
zarzet fcec0942b9 refactor(android): drop SDK checks below minSdk 24
Flutter 3.47.7 sets flutter.minSdkVersion to 24, which
android/app/build.gradle.kts uses as minSdk. The N (24) checks around
StorageManager.storageVolumes and the LOLLIPOP (21) check around
finishAndRemoveTask were therefore always true, and their else branches
could never run. Keep the true-branch bodies. Checks for API levels
above 24 are unchanged.
2026-10-18 23:01:04 +07:00
zarzet 8aca5e4ef2 refactor(android): drop unreachable dispatch cases and dead channel handlers
RustCoreBackend.invokeApplication handled readFileMetadata,
editFileMetadata and cancelNativeDataJob, but MainActivity intercepts
all three first: the metadata methods are in nativeBackendMethods and
dispatchBackendApplication answers cancelNativeDataJob before it calls
invokeApplication. No Kotlin code calls invokeApplication with those
names.

Dart never sends these channel methods, so their handlers go on every
platform:

- shareMultipleContentUris (Android) and getAvailableLyricsProviders
  (Android and iOS) have no Dart caller.
- scanLibraryFolderIncrementalFromSnapshot and
  scanSafTreeIncrementalFromSnapshot are called only from the Dart host
  branch of the library scan, which runs only when
  supportsCoreBackend is false, that is never on Android or iOS. The
  unreachable Dart wrappers are removed separately.

The allowlist and the when cases in MainActivity stay in sync (70
names). The UniFFI exports get_available_lyrics_providers_json and
scan_library_folder_incremental_from_snapshot were used only by the
removed handlers; the backend methods behind them stay.
2026-10-18 23:01:04 +07:00
zarzet ca950dc35a refactor(android): remove backend switches that became constants
Rust is the only backend, so several single-backend switches had become
constants and their other branches could never run:

- CoreBackend.supportsOutputDescriptors was always false. The
  descriptor branch in SafDownloadHandler and its pfd/detachFd cleanup
  never ran, and the Rust planner rejects output_fd anyway.
- routesApplication was always true on Android and iOS. Drop the member,
  the "go" value of getBackendImplementations (the reply keys and the
  "rust" value Dart receives are unchanged), the iOS routing guard and
  the interface defaults that threw for unrouted methods.
- cleanupExtensions(), waitForDownloadProgressDelta and
  scanCueForLibrary had no production caller. Dart reaches cleanup
  through the cleanupExtensions channel method, and RustCoreBackend
  overrides openDownloadProgress, so the polling default goes too.

The UniFFI exports DownloadState.wait_progress_delta and
ExtensionManager.scan_cue_file_for_library were used only by those
Kotlin overrides. Bindings are generated at build time by
scripts/build_rust_backend.sh; no generated binding is tracked.
2026-10-18 23:01:04 +07:00
zarzet 66d480dbdc fix(storage): retain legacy Android cipher migration support 2026-10-18 04:09:16 +07:00
zarzet 75cd4c39b2 feat(android): refresh launcher widgets with adaptive expressive layouts 2026-10-18 03:10:40 +07:00
zarzet e0dfa7eb69 refactor(android): scope Rust download state handles consistently 2026-10-18 00:46:53 +07:00
zarzet 504c3cd18b refactor(android): share native album artist resolution 2026-10-18 00:46:10 +07:00
zarzet fdcd291c78 refactor(android): remove unreachable backend dispatch fallbacks 2026-10-18 00:46:09 +07:00
zarzet 3d11169f21 fix(network): request Android 17 local network access before NAS connections 2026-10-17 16:18:41 +07:00
zarzet 11c6cf9915 feat(player): synchronize music haptics with local playback 2026-10-17 16:18:37 +07:00
zarzet 40f65d3a4d feat(player): show audio source processing and output details 2026-10-17 16:18:32 +07:00
zarzet 3dc2d69051 fix(audio): preserve FLAC precision in Android bit-perfect playback 2026-10-15 00:28:17 +07:00
zarzet c0fd506c78 fix(storage): preserve audio MIME when publishing SAF downloads
Honor the requested MIME across publication paths, retain the audio suffix in temporary names, and exclude unfinished documents from full and incremental scans. Verify MIME and byte integrity across four formats and publication modes.
2026-10-13 19:38:11 +07:00
zarzet 186c66aeb8 fix(lyrics): refresh LRC sidecars in their actual SAF folder
Resolve opaque SAF document ancestry before writing adjacent lyrics. Propagate failed requested LRC writes and cover native word-synced refresh in regression tests.
2026-10-13 19:38:00 +07:00
zarzet e3b69a25ef fix(download): probe M4A streams before preserving requested FLAC
Provider and decryption extensions describe the downloaded container, not
its audio codec. A decrypted M4A/MP4 can still carry FLAC, so a requested
FLAC output now reaches the codec probe instead of being preserved early.
Lossy streams keep their native container and still receive metadata.
2026-10-13 18:27:16 +07:00
zarzet ac8523d789 feat(metadata): add per-field download tag separators 2026-10-12 12:11:06 +07:00
zarzet ebaa6c5c1e test(android): accept validated FLAC fallback across FFmpeg versions 2026-10-11 16:14:01 +07:00
zarzet d611590039 chore(android): update Gradle Kotlin NDK and native build dependencies 2026-10-11 14:33:52 +07:00
zarzet 1b9c35f322 fix(downloads): preserve browser verification and queues across restarts 2026-10-09 18:07:49 +07:00
zarzet 37258a6160 fix(setup): recover folder permissions after Android restarts 2026-10-09 18:07:38 +07:00
zarzet c7b1d0b0ec fix(metadata): preserve original artwork resolution for SAF files 2026-10-09 10:34:49 +07:00
zarzet 2ded1cff68 perf(downloads): batch queue cancellation and progress cleanup 2026-10-08 08:47:47 +07:00
zarzet c67d2a2dd2 perf(downloads): batch cancellation resets for retry 2026-10-08 06:55:26 +07:00
zarzet 6325c4769c fix(downloads): preserve actual provider audio format 2026-10-08 01:50:36 +07:00
zarzet d1de833184 perf(library): index scans and snapshots with native SQLite workers
Move full and incremental ingestion, source snapshots, path keys, and download exclusion to native transactions. Preserve schema 17, FTS, WAL coordination, cancellation, and Android SAF timestamp backfill.
2026-10-06 23:29:33 +07:00
zarzet d693e1a479 perf(theme): extract cover palettes with native quantization
Port the pinned Material quantizer and Dart RNG compatibility to Rust while keeping Material Score and final color schemes in Dart. Include exact palette fixtures, licenses, and Kotlin worker ABI coverage.
2026-10-06 23:27:38 +07:00
zarzet 867371cb67 feat(native): add cancellable data workers and streamed file hashing
Introduce Android, iOS, and Dart worker dispatch with queued cancellation, binary inputs, and background JSON codecs. Move APK verification to streamed native SHA256 while retaining the isolated fallback.
2026-10-06 23:25:39 +07:00
zarzet ca747f8ce2 fix(android): release temporary media on failed SAF operations 2026-10-06 22:00:44 +07:00
zarzet f61e815e24 perf(android): trim platform assets and release Dart symbols 2026-10-06 21:58:55 +07:00
zarzet b8c50b1527 perf(android): reduce release APK size
Keep Dart debug data outside libapp.so and archive matching symbols and R8 mappings in CI. Pack native relocations, preserve JNI exports, and recompress PNG assets losslessly.

ARM64 APK shrinks from 80,306,680 to 76,080,247 bytes (5.26%). Verified with 1,877 Flutter tests, 19 native device tests, Discord SDK integration, and release startup on a 16 KiB Android emulator.
2026-10-06 15:22:42 +07:00
zarzet b8787168d1 refactor(downloads): isolate typed results and audio finalization 2026-10-06 13:09:26 +07:00
zarzet 7493c37698 refactor(android): isolate native download history persistence 2026-10-06 13:08:14 +07:00
zarzet d98ab4852d fix(library): distinguish unavailable storage from missing files 2026-10-06 13:08:12 +07:00
zarzet 772bd97f7d fix(downloads): preserve filenames after decryption and conversion 2026-10-06 00:04:14 +07:00
zarzet 5f0577837d perf(widget): publish artwork only for installed consumers 2026-10-04 01:41:55 +07:00
zarzet c69f2cef9f perf(library): scan SAF CUE audio through live descriptors 2026-10-04 01:41:35 +07:00
zarzet 4e20102bdd perf(usb): reuse PCM buffers and respect native ring capacity 2026-10-04 01:40:59 +07:00
zarzet 9c0b22e2c8 feat(build): require Discord in production and keep Lite opt-in 2026-10-04 01:40:54 +07:00
zarzet 541bfc4002 perf(media): shrink FFmpeg while preserving HTTPS motion artwork 2026-10-04 01:35:48 +07:00
zarzet f035538778 fix(library): expose failed scan files and reasons in app logs 2026-10-03 17:57:35 +07:00
zarzet e35a3cbb84 fix(library): scan remote SAF folders when root metadata is unavailable 2026-10-03 13:40:39 +07:00
zarzet fb41a86f5a fix(library): match SAF documents across folder tree aliases 2026-10-03 13:40:39 +07:00
zarzet 04ee6bc6f2 fix(lyrics): grant scoped access to selected audio files
Open temporary media directory grants for reading, embedding and exporting lyrics on iOS and Android. Resolve native file aliases consistently while retaining extension storage restrictions.

Validate with 4 iOS integration tests, 42 Flutter tests, 6 Rust file capability tests, and Android Kotlin compilation. Refs #631.
2026-10-03 12:19:03 +07:00
zarzet 115602b84e fix(library): reject filename guesses from failed NAS metadata reads 2026-10-03 03:26:35 +07:00
zarzet 0b2cf0e4e5 feat(discord): add opt-in mobile rich presence with track artwork 2026-10-03 02:14:11 +07:00
zarzet bbe2caa754 fix(android): preserve remote SAF descriptors for audio and artwork 2026-10-03 02:14:06 +07:00
zarzet b767bd16d8 fix(playback): refresh notification favorite and shuffle controls 2026-10-03 02:14:01 +07:00
zarzet 70f8bd7f35 feat(extensions): support personal account forms and direct downloads 2026-10-02 19:21:58 +07:00
zarzet 4eef5542be fix(metadata): recognize featured artist credits consistently
Handle feature and featured separators across display, Android finalization and Rust tag writing. Split conjunction credits only when separate artist IDs confirm them, and offer a picker for multi-artist navigation.
2026-10-02 18:10:00 +07:00