FastMediaSorter v2: Tech Stack
Version sources of truth:
- Build system and plugin versions:
build.gradle.kts - App dependency and variant definitions:
app_v2/build.gradle.kts - Wear dependency and packaging definitions:
wear/build.gradle.kts - Operational build commands and release flow:
docs/DEV_OPS.md
There is no Gradle version catalog in this repo. Runtime dependency versions are declared inline in the module Gradle files.
The pins below are generated by scripts/quality/generate-toolchain-pins.ps1 - do not hand-edit:
- compileSdk: 35
- targetSdk: 35
- minSdk (standard): 26
- minSdk (legacy): 23
- Kotlin: 2.2.10
- Room: 2.7.0
- Media3 (ExoPlayer): 1.2.1
- Glide: 4.16.0
Build System
- Gradle wrapper:
9.4.1 - Android Gradle Plugin:
9.2.1 - Kotlin Gradle Plugin:
2.2.10 - Kotlin Compose plugin:
2.2.10 - KSP:
2.3.8 - Hilt Gradle plugin:
2.59 - Chaquopy:
17.0.0(noLegalonly) - Java toolchain / bytecode target:
17 - Modules:
:app_v2,:wear - Repositories: Google Maven, Maven Central, Gradle Plugin Portal, Microsoft Duo public Maven feed, JitPack
- Checked-in dependency declarations in Gradle files:
140
Platform and Packaging
- Main app namespace / base applicationId:
com.sza.fastmediasorter - Wear namespace / applicationId:
com.sza.fastmediasorter.wear app_v2minSdk:26by default,23inlegacywearminSdk:28compileSdk/targetSdk:35for both modules- NDK:
27.2.12479018(r27c) inapp_v2 coreLibraryDesugaringis enabled inapp_v2for API 23-25 support- Annotation processing split:
app_v2useskapt,wearusesksp
Variant Matrix
- Main app product flavors:
standard,noLegal,lite,photos,legacy,vr - Main app build types:
debug,staging,release - Main app variant count:
18 - Wear build types:
debug,release - Total application variant count across both modules:
20
Flavor summary:
standard: full phone/tablet build, 4 ABIs (arm64-v8a,armeabi-v7a,x86,x86_64)lite: lighter local-first build, 4 ABIsphotos: image/cloud-focused build, 4 ABIslegacy: API 23-25 full-feature build, 4 ABIsnoLegal: sideload-only full build with VR/XR and Python surface, 2 ABIs (arm64-v8a,x86_64)vr: OpenXR headset build, 1 ABI (arm64-v8a)
Build type summary:
debug: debuggable, not minified,applicationIdSuffix ".debug",versionNameSuffix "-DEBUG"staging:initWith(release), debuggable, no minify, no resource shrink, suffixes.staging/-STAGINGrelease: minified, resource shrinking enabled, nativedebugSymbolLevel = FULL, release signing required
Build Outputs and Size Facts
- Main app APK outputs:
app_v2/build/outputs/apk/<flavor>/<buildType>/ - Wear APK outputs:
wear/build/outputs/apk/<buildType>/ - Main app AAB outputs:
app_v2/build/outputs/bundle/<flavor>Release/ - Main app metadata example:
app_v2/build/outputs/apk/standard/debug/output-metadata.json
Latest local artifact found during this document refresh:
- Variant:
standardDebug - applicationId:
com.sza.fastmediasorter.debug - versionCode:
260621154 - versionName:
2.60.6211.547-DEBUG - File:
app_v2/build/outputs/apk/standard/debug/FastMediaSorter_standard_debug_v2.60.6211.547-DEBUG.apk - Size:
118,188,207bytes (112.71 MiB) - Last write time:
2026-06-24 02:04:41local time
Additional local binary footprint:
- Bundled custom decoder AAR:
app_v2/libs/fms-ffmpeg-dts.aar - AAR size:
11,495,586bytes (10.96 MiB)
Size interpretation:
- The observed
standardDebugAPK is a universal local debug artifact, not a Play-delivered split - It carries 4 ABIs, debug packaging, and no minification or resource shrinking
- Its size is therefore expected to be much larger than a release AAB-derived install on a single device
At the time of this refresh, no local Wear APK output or local AAB output was present under build/outputs.
Approximate Project Scale
Snapshot date for the metrics below: 2026-06-24.
Code volume:
- Production Kotlin/Java files:
1,749 - Production Kotlin/Java lines:
246,348 - Test Kotlin/Java files:
377 - Test Kotlin/Java lines:
34,696 - Combined Kotlin/Java files:
2,126 - Combined Kotlin/Java lines:
281,044 - XML resource files:
837 - XML resource lines:
54,849 - Layout XML files only:
292
Model and state surface:
- Files in explicit
model/ormodels/directories: about62 - Of those, domain-model files: about
56 - Data-model files: about
2 - UI-model files: about
4 - Room entity files:
17
Screen surface:
- Activity files:
43 - Fragment files:
29 - Compose
*Screen.ktfiles:12 - Dialog / dialog-fragment files:
42 - ViewModel files:
39 - Practical user-visible screen estimate: roughly
80-120surfaces, depending on whether dialogs, modal flows, and orientation-specific hosts are counted as separate screens
Engineering effort estimate:
- Rough engineering-only estimate for the current codebase shape: about
6,000-9,000person-hours - Broader delivery estimate including architecture churn, integration debugging, regression handling, release plumbing, and polish: about
8,000-12,000person-hours - This is an inference, not a historical log. The estimate is driven by the size of the production code,
20application variants acrossapp_v2+wear, multiple network/cloud/media integrations, and the custom build/release automation around them
Dependency Highlights
- DI and persistence: Hilt
2.59, Room2.7.0, WorkManager2.9.0, DataStore1.0.0 - UI: Jetpack Compose BOM
2024.02.00, Material 3, Activity1.10.1, Lifecycle2.7.0, ConstraintLayout2.1.4 - Media: Media3
1.2.1(exoplayer,ui,common,session,effect, plus flavor-mountedhls,dash,rtsp,midi) - Imaging and capture: Glide
4.16.0, Coil2.5.0(Wear), CameraX1.5.3, PhotoView2.3.0, ExifInterface1.3.7 - Network and auth: SMBJ
0.12.1, JSch0.2.26(app) /0.2.17(wear), Commons Net3.10.0, OkHttp4.12.0, Retrofit2.9.0, AppAuth0.11.1 - Cloud SDKs: Play Services Auth
21.0.0, Dropbox Core SDK5.4.5, MSAL6.0.1 - OCR, translation, docs, archives: ML Kit Translate
17.0.3, Language ID17.0.6, Tesseract4Android4.8.0, epub4j-core4.2, jsoup1.17.2, Markwon4.6.2, zip4j2.11.5 - Sideload / XR-only surface: Chaquopy Python
3.12,yt-dlp==2026.6.9, OpenXR loader1.1.48, NewPipeExtractorv0.26.1
Feature Surface Notes
standardandlegacykeep the broadest phone/tablet surface: media, cloud, documents, translation, Wear companion, Castliteremoves cloud, documents, local-network protocols, translation, persistent audio, and Wear companion to reduce app surfacephotoskeeps images plus cloud/network storage, but removes audio/video/document featuresnoLegalextends the full build with sideload-only integrations and XR-capable runtime hooksvrkeeps full media capability but packages onlyarm64-v8aand mounts OpenXR-specific native/runtime pieces
Network Protocol Notes
- SMB: SMBJ (
com.hierynomus:smbj:0.12.1) - FTP: Apache Commons Net (
commons-net:3.10.0) - SFTP: JSch (
com.github.mwiede:jsch) in both modules, with different pinned versions - Internet streams: Media3 selects HLS, DASH, RTSP, or progressive playback sources at runtime
- Cast path: Google Cast SDK
21.4.0+ MediaRouter1.7.0+ in-processnanohttpd:2.3.1proxy - Public cleartext
http://streams remain supported because many radio/stream endpoints are still unencrypted