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.
58 lines
2.1 KiB
Bash
Executable File
58 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# The gate. Everything that has to be true before a change is finished, in one command:
|
|
#
|
|
# ./tools/verify.sh # what every change has to pass
|
|
# ./tools/verify.sh --release # ...and an R8 release build, which is what the nightly runs
|
|
# GRADLE_FLAGS=--offline ./tools/verify.sh # keeps working without a network
|
|
#
|
|
# Cheapest first, so a stale document fails in a second rather than after a release build. Each step
|
|
# is here because it has caught a real defect in this project at least once; nothing is on the list
|
|
# because it is fashionable.
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
release=false
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--release) release=true ;;
|
|
*) echo "verify: unknown option '$arg' (only --release is understood)" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
# Word splitting is intended here: GRADLE_FLAGS is a place to put several flags.
|
|
# shellcheck disable=SC2086
|
|
gradle() { ./gradlew ${GRADLE_FLAGS:-} "$@" --console=plain; }
|
|
|
|
step() { printf '\n\033[1m== %s\033[0m\n' "$1"; }
|
|
|
|
step "Code map is current"
|
|
python3 tools/make-code-map.py --check
|
|
|
|
step "Kotlin static analysis (detekt, against the baseline)"
|
|
gradle :app:detekt
|
|
|
|
step "JVM unit tests"
|
|
gradle :app:testDebugUnitTest
|
|
|
|
step "Android Lint"
|
|
gradle :app:lintDebug
|
|
|
|
if $release; then
|
|
step "Release build (R8)"
|
|
# Signed when keystore.properties happens to be present, unsigned otherwise — either way R8
|
|
# runs, and a release-only defect (a class reached only through a resource, for instance) is
|
|
# exactly what this step is for.
|
|
gradle :app:assembleRelease
|
|
|
|
step "Benchmark APKs compile"
|
|
# No device: this only proves that :benchmark still compiles against the app's benchmark build
|
|
# type, which is the thing that rots silently between device runs. :baselineprofile is included for
|
|
# the same reason — its generator only runs on a device with API 33+, so nothing else would notice it
|
|
# breaking.
|
|
gradle :app:assembleBenchmark :benchmark:assembleDebug :baselineprofile:assembleBenchmark
|
|
fi
|
|
|
|
printf '\n\033[1mverify: all checks passed\033[0m\n'
|