Skip to content

Commit 246200f

Browse files
authored
Merge pull request #754 from android/tm/metrics-one-folder
Compose compiler metrics saved into one folder
2 parents e96e54f + d15d269 commit 246200f

File tree

7 files changed

+39
-33
lines changed

7 files changed

+39
-33
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ Run the following command to get and analyse compose compiler metrics:
154154
./gradlew assembleRelease -PenableComposeCompilerMetrics=true -PenableComposeCompilerReports=true
155155
```
156156

157-
The reports files will be added to build/compose-reports in each module. The metrics files will be
158-
added to build/compose-metrics in each module.
157+
The reports files will be added to [build/compose-reports](build/compose-reports). The metrics files will also be
158+
added to [build/compose-metrics](build/compose-metrics).
159159

160160
For more information on Compose compiler metrics, see [this blog post](https://medium.com/androiddevelopers/jetpack-compose-stability-explained-79c10db270c8).
161161

benchmarks/src/main/java/com/google/samples/apps/nowinandroid/Utils.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package com.google.samples.apps.nowinandroid
1818

19+
import androidx.test.uiautomator.BySelector
1920
import androidx.test.uiautomator.Direction
2021
import androidx.test.uiautomator.UiDevice
2122
import androidx.test.uiautomator.UiObject2
23+
import androidx.test.uiautomator.Until
2224
import com.google.samples.apps.nowinandroid.benchmarks.BuildConfig
25+
import java.io.ByteArrayOutputStream
2326

2427
/**
2528
* Convenience parameter to use proper package name with regards to build type and build flavor.
@@ -38,3 +41,24 @@ fun UiDevice.flingElementDownUp(element: UiObject2) {
3841
waitForIdle()
3942
element.fling(Direction.UP)
4043
}
44+
45+
/**
46+
* Waits until an object with [selector] if visible on screen and returns the object.
47+
* If the element is not available in [timeout], throws [AssertionError]
48+
*/
49+
fun UiDevice.waitAndFindObject(selector: BySelector, timeout: Long): UiObject2 {
50+
if (!wait(Until.hasObject(selector), timeout)) {
51+
throw AssertionError("Element not found on screen in ${timeout}ms (selector=$selector)")
52+
}
53+
54+
return findObject(selector)
55+
}
56+
57+
/**
58+
* Helper to dump window hierarchy into a string.
59+
*/
60+
fun UiDevice.dumpWindowHierarchy(): String {
61+
val buffer = ByteArrayOutputStream()
62+
dumpWindowHierarchy(buffer)
63+
return buffer.toString()
64+
}

benchmarks/src/main/java/com/google/samples/apps/nowinandroid/baselineprofile/BaselineProfileGenerator.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.baselineprofile
1818

1919
import androidx.benchmark.macro.junit4.BaselineProfileRule
2020
import com.google.samples.apps.nowinandroid.PACKAGE_NAME
21+
import com.google.samples.apps.nowinandroid.allowNotifications
2122
import com.google.samples.apps.nowinandroid.bookmarks.goToBookmarksScreen
2223
import com.google.samples.apps.nowinandroid.foryou.forYouScrollFeedDownUp
2324
import com.google.samples.apps.nowinandroid.foryou.forYouSelectTopics
@@ -39,7 +40,7 @@ class BaselineProfileGenerator {
3940
// This block defines the app's critical user journey. Here we are interested in
4041
// optimizing for app startup. But you can also navigate and scroll
4142
// through your most important UI.
42-
43+
allowNotifications()
4344
pressHome()
4445
startActivityAndWait()
4546

benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ForYouActions.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import androidx.test.uiautomator.By
2121
import androidx.test.uiautomator.Until
2222
import androidx.test.uiautomator.untilHasChildren
2323
import com.google.samples.apps.nowinandroid.flingElementDownUp
24+
import com.google.samples.apps.nowinandroid.waitAndFindObject
2425

2526
fun MacrobenchmarkScope.forYouWaitForContent() {
2627
// Wait until content is loaded by checking if topics are loaded
2728
device.wait(Until.gone(By.res("loadingWheel")), 5_000)
2829
// Sometimes, the loading wheel is gone, but the content is not loaded yet
2930
// So we'll wait here for topics to be sure
30-
val obj = device.findObject(By.res("forYou:topicSelection"))
31+
val obj = device.waitAndFindObject(By.res("forYou:topicSelection"), 10_000)
3132
// Timeout here is quite big, because sometimes data loading takes a long time!
3233
obj.wait(untilHasChildren(), 60_000)
3334
}

benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ScrollForYouFeedBenchmark {
4343
metrics = listOf(FrameTimingMetric()),
4444
compilationMode = compilationMode,
4545
iterations = 10,
46-
startupMode = StartupMode.COLD,
46+
startupMode = StartupMode.WARM,
4747
setupBlock = {
4848
// Start the app
4949
pressHome()

benchmarks/src/main/java/com/google/samples/apps/nowinandroid/startup/StartupBenchmark.kt

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ package com.google.samples.apps.nowinandroid.startup
1919
import androidx.benchmark.macro.BaselineProfileMode.Disable
2020
import androidx.benchmark.macro.BaselineProfileMode.Require
2121
import androidx.benchmark.macro.CompilationMode
22-
import androidx.benchmark.macro.StartupMode
2322
import androidx.benchmark.macro.StartupMode.COLD
24-
import androidx.benchmark.macro.StartupMode.HOT
25-
import androidx.benchmark.macro.StartupMode.WARM
2623
import androidx.benchmark.macro.StartupTimingMetric
2724
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
2825
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
@@ -34,31 +31,12 @@ import org.junit.Test
3431
import org.junit.runner.RunWith
3532

3633
/**
34+
* Enables app startups from various states of baseline profile or [CompilationMode]s.
3735
* Run this benchmark from Studio to see startup measurements, and captured system traces
3836
* for investigating your app's performance from a cold state.
3937
*/
4038
@RunWith(AndroidJUnit4ClassRunner::class)
41-
class ColdStartupBenchmark : AbstractStartupBenchmark(COLD)
42-
43-
/**
44-
* Run this benchmark from Studio to see startup measurements, and captured system traces
45-
* for investigating your app's performance from a warm state.
46-
*/
47-
@RunWith(AndroidJUnit4ClassRunner::class)
48-
class WarmStartupBenchmark : AbstractStartupBenchmark(WARM)
49-
50-
/**
51-
* Run this benchmark from Studio to see startup measurements, and captured system traces
52-
* for investigating your app's performance from a hot state.
53-
*/
54-
@RunWith(AndroidJUnit4ClassRunner::class)
55-
class HotStartupBenchmark : AbstractStartupBenchmark(HOT)
56-
57-
/**
58-
* Base class for benchmarks with different startup modes.
59-
* Enables app startups from various states of baseline profile or [CompilationMode]s.
60-
*/
61-
abstract class AbstractStartupBenchmark(private val startupMode: StartupMode) {
39+
class StartupBenchmark {
6240
@get:Rule
6341
val benchmarkRule = MacrobenchmarkRule()
6442

@@ -81,9 +59,10 @@ abstract class AbstractStartupBenchmark(private val startupMode: StartupMode) {
8159
metrics = listOf(StartupTimingMetric()),
8260
compilationMode = compilationMode,
8361
iterations = 10,
84-
startupMode = startupMode,
62+
startupMode = COLD,
8563
setupBlock = {
8664
pressHome()
65+
allowNotifications()
8766
},
8867
) {
8968
startActivityAndWait()

build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import org.gradle.api.Project
2121
import org.gradle.kotlin.dsl.dependencies
2222
import org.gradle.kotlin.dsl.withType
2323
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
24-
import java.io.File
2524

2625
/**
2726
* Configure Compose-specific options
@@ -55,9 +54,11 @@ internal fun Project.configureAndroidCompose(
5554
private fun Project.buildComposeMetricsParameters(): List<String> {
5655
val metricParameters = mutableListOf<String>()
5756
val enableMetricsProvider = project.providers.gradleProperty("enableComposeCompilerMetrics")
57+
val relativePath = projectDir.relativeTo(rootDir)
58+
5859
val enableMetrics = (enableMetricsProvider.orNull == "true")
5960
if (enableMetrics) {
60-
val metricsFolder = File(project.buildDir, "compose-metrics")
61+
val metricsFolder = rootProject.buildDir.resolve("compose-metrics").resolve(relativePath)
6162
metricParameters.add("-P")
6263
metricParameters.add(
6364
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath
@@ -67,7 +68,7 @@ private fun Project.buildComposeMetricsParameters(): List<String> {
6768
val enableReportsProvider = project.providers.gradleProperty("enableComposeCompilerReports")
6869
val enableReports = (enableReportsProvider.orNull == "true")
6970
if (enableReports) {
70-
val reportsFolder = File(project.buildDir, "compose-reports")
71+
val reportsFolder = rootProject.buildDir.resolve("compose-reports").resolve(relativePath)
7172
metricParameters.add("-P")
7273
metricParameters.add(
7374
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath

0 commit comments

Comments
 (0)