4846454645
The profile is real: 13193 lines in app/src/main/baseline-prof.txt, 584 of them the app's own classes, bundled into the release APK as assets/dexopt/baseline.prof. It is produced by a new :baselineprofile test module that walks the first journey - roots screen, one volume opened - under the androidx.baselineprofile plugin, and :app now depends on androidx.profileinstaller so the bundled profile is applied at install time. Two device facts decided how it was made. Collection requires API 33+ (BaselineProfileRule refuses Android 12 outright), so it ran on the API 35 AVD that was already in ~/.android/avd; that emulator is software-rendered and needs androidx.benchmark.suppressErrors=EMULATOR for any macrobenchmark. And the release build needed profileable android:shell=true, which is why app/src/release/AndroidManifest.xml exists and says why: the same APK is both the thing measured and the thing shipped, so the profile's class names are the ones in the shipped dex. The effect is not measured, and PERFORMANCE.md says so: 7404 ms median without the profile against 9005 ms with it, run to run, because a TCG emulator varies by more than a profile can buy. What remains is one run on a physical API 33+ phone, with the two compile commands documented. The emulator did settle the other open question - FrameTimingMetric there reports frameDurationCpuMs and frameOverrunMs, the metrics this phone cannot produce at all. :baselineprofile is compiled by tools/verify.sh --release like :benchmark, so it cannot rot between device runs.
113 lines
6.8 KiB
TOML
113 lines
6.8 KiB
TOML
[versions]
|
|
agp = "9.1.0"
|
|
kotlin = "2.4.10"
|
|
# Static analysis for Kotlin, driven by tools/verify.sh. 1.23.8 is the newest release on the plugin
|
|
# portal (there is no 2.x there yet). It is used through its CLI rather than its Gradle plugin: the
|
|
# plugin runs the analysis inside the build's own JVM, and detekt 1.23 cannot parse JDK 25's version
|
|
# string — see the task in app/build.gradle.kts. The findings that exist today are frozen in
|
|
# config/detekt/baseline.xml, so the gate fails on a new one rather than on the backlog.
|
|
detekt = "1.23.8"
|
|
|
|
# AndroidX / Compose
|
|
coreKtx = "1.18.0"
|
|
lifecycle = "2.10.0"
|
|
activityCompose = "1.13.0"
|
|
# SAF backend: DocumentFile over a persisted tree URI.
|
|
documentfile = "1.1.0"
|
|
# Compose BOM 2026.06.01 -> Compose UI/foundation 1.11.4, material3 1.4.0.
|
|
# Newer BOMs (2026.08.00+) ship Compose 1.12.x, which requires compileSdk 37 —
|
|
# that is newer than what AGP 9.1.0 supports (36) and newer than the API level
|
|
# Google Play requires for targetSdk, so we deliberately stay on 1.11.4.
|
|
composeBom = "2026.06.01"
|
|
# Coil 3.6.x requires compileSdk 37; 3.5.0 requires 36.
|
|
coil = "3.5.0"
|
|
|
|
# Kotlin libraries
|
|
coroutines = "1.9.0"
|
|
|
|
# Archives. Commons Compress is pure Java (zip/tar/gzip/bzip2/xz, 7z read),
|
|
# so it adds no native code and therefore no NDK dependency to the build.
|
|
commonsCompress = "1.27.1"
|
|
# Commons Compress declares its LZMA/LZMA2 support — the `.xz` compressor and the 7z
|
|
# format — against this library, as an *optional* dependency. Optional means it is NOT
|
|
# pulled in transitively, so leaving it out breaks `.xz` and `.7z` at **runtime** with
|
|
# NoClassDefFoundError rather than failing the build. 1.10 is the version Commons
|
|
# Compress 1.27.1 itself compiles against.
|
|
xz = "1.10"
|
|
|
|
# Testing
|
|
junit = "4.13.2"
|
|
robolectric = "4.17"
|
|
# Debug-only leak detection: a Compose screen that outlives its screen is invisible in tests and
|
|
# obvious in a heap dump. Never shipped — `debugImplementation` below.
|
|
leakcanary = "2.14"
|
|
|
|
# Macrobenchmark (the `:benchmark` module). Its own versions because it is a test APK that is never
|
|
# part of the app.
|
|
benchmark = "1.5.0"
|
|
# Baseline profiles: the Gradle plugin generates one from a device run, and profileinstaller applies it
|
|
# on the device at install time. 1.5.0 is the newest stable and the one that knows AGP 9.
|
|
baselineprofile = "1.5.0"
|
|
profileinstaller = "1.4.0"
|
|
androidxTestJunit = "1.3.0"
|
|
uiautomator = "2.4.0"
|
|
androidxTestRunner = "1.7.0"
|
|
|
|
[libraries]
|
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
|
androidx-documentfile = { group = "androidx.documentfile", name = "documentfile", version.ref = "documentfile" }
|
|
|
|
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
|
|
androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" }
|
|
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" }
|
|
|
|
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
|
|
|
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
|
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
|
|
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
|
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
|
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
|
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
|
androidx-compose-material-icons-core = { group = "androidx.compose.material", name = "material-icons-core" }
|
|
androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
|
|
|
|
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
|
|
|
coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" }
|
|
# Decodes a frame out of a video, so a video row shows what is in the clip rather than a film icon.
|
|
# Same version as coil-compose on purpose — a decoder is part of Coil's pipeline, not a plugin beside
|
|
# it — and its POM adds nothing coil-compose does not already bring (coil-core, kotlin-stdlib,
|
|
# core-ktx). No ExoPlayer and no media3, which is what makes this acceptable for a thumbnail.
|
|
coil-video = { group = "io.coil-kt.coil3", name = "coil-video", version.ref = "coil" }
|
|
|
|
commons-compress = { group = "org.apache.commons", name = "commons-compress", version.ref = "commonsCompress" }
|
|
# Commons Compress's LZMA/LZMA2 support: the `.xz` compressor and the 7z format.
|
|
xz = { group = "org.tukaani", name = "xz", version.ref = "xz" }
|
|
|
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
|
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
|
|
# Compose rendering tests, run on the JVM through Robolectric. Versions come from the Compose BOM.
|
|
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
|
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
|
leakcanary-android = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" }
|
|
|
|
# Macrobenchmark, for the `:benchmark` module only.
|
|
androidx-benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmark" }
|
|
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestJunit" }
|
|
androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
|
|
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
|
|
# Installs the baseline profile bundled in the APK on first run.
|
|
androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "profileinstaller" }
|
|
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
|
|
|
|
# Static analysis, run by the :app:detekt task from its own configuration — never an app dependency.
|
|
detekt-cli = { group = "io.gitlab.arturbosch.detekt", name = "detekt-cli", version.ref = "detekt" }
|
|
|
|
[plugins]
|
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
|
# NOTE: `org.jetbrains.kotlin.android` is intentionally absent — AGP 9.x provides
|
|
# built-in Kotlin support and applying that plugin is now an error.
|
|
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
|
androidx-baselineprofile = { id = "androidx.baselineprofile", version.ref = "baselineprofile" }
|