Publish current app and server

This commit is contained in:
ponzischeme89
2026-08-02 22:10:19 +12:00
parent a265636139
commit 1ed180c739
203 changed files with 23933 additions and 2788 deletions
@@ -0,0 +1,51 @@
package com.ponzischeme89.memby.benchmark
import android.view.KeyEvent
import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Records the classes and methods the launcher touches between process start and the
* first few D-pad moves, so ART can compile them ahead of time instead of interpreting
* them on a TV box that has nothing to spare.
*
* Run against a real television:
*
* .\gradlew.bat :app:generateReleaseBaselineProfile
*
* The output lands in app/src/release/generated/baselineProfiles and is checked in, so
* an ordinary `assembleRelease` needs no device. Regenerate it after a change that moves
* the startup path — a stale profile is not harmful, just progressively less useful.
*/
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
@get:Rule val rule = BaselineProfileRule()
@Test
fun startupAndBrowse() = rule.collect(
packageName = "com.ponzischeme89.memby",
// The signed-in launcher renders from HomeCache before the network answers, so a
// cold start reaches real rows without waiting on the gateway. Include enough
// D-pad movement to pull in the row/card composables and Coil's decode path,
// which is where the first-scroll jank lives.
includeInStartupProfile = true,
) {
pressHome()
startActivityAndWait()
browseHome()
}
private fun MacrobenchmarkScope.browseHome() {
repeat(4) { device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) }
device.waitForIdle()
device.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN)
repeat(3) { device.pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT) }
device.waitForIdle()
device.pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN)
device.waitForIdle()
}
}
@@ -15,24 +15,35 @@ import org.junit.runner.RunWith
class HomeBenchmark {
@get:Rule val benchmarkRule = MacrobenchmarkRule()
/**
* The baseline for comparison: no ahead-of-time compilation at all. Keep this around
* — the only way to know whether [coldStartToHomeWithProfile] is earning its keep is
* to see the two numbers side by side.
*/
@Test
fun coldStartToHome() = benchmarkRule.measureRepeated(
packageName = "com.ponzischeme89.memby",
fun coldStartToHomeNoCompilation() = measureColdStart(CompilationMode.None())
/** What a viewer installing a release APK actually gets. */
@Test
fun coldStartToHomeWithProfile() = measureColdStart(CompilationMode.Partial())
private fun measureColdStart(mode: CompilationMode) = benchmarkRule.measureRepeated(
packageName = PACKAGE_NAME,
metrics = listOf(StartupTimingMetric()),
compilationMode = CompilationMode.None(),
compilationMode = mode,
startupMode = StartupMode.COLD,
iterations = 3,
iterations = 5,
setupBlock = { pressHome() },
measureBlock = { startActivityAndWait() },
)
@Test
fun homeDpadAndRows() = benchmarkRule.measureRepeated(
packageName = "com.ponzischeme89.memby",
packageName = PACKAGE_NAME,
metrics = listOf(FrameTimingMetric()),
compilationMode = CompilationMode.None(),
compilationMode = CompilationMode.Partial(),
startupMode = StartupMode.WARM,
iterations = 3,
iterations = 5,
setupBlock = { startActivityAndWait() },
measureBlock = { exerciseHome() },
)
@@ -44,4 +55,8 @@ class HomeBenchmark {
device.pressKeyCode(android.view.KeyEvent.KEYCODE_DPAD_RIGHT)
device.waitForIdle()
}
private companion object {
const val PACKAGE_NAME = "com.ponzischeme89.memby"
}
}