Skip to content

Commit c05e27b

Browse files
authored
Merge pull request #276 from YAPP-Github/feature/#275-benchmark-host-activity
[FEATURE] Benchmark Host Activity 생성
2 parents e33681a + 6ee1ab8 commit c05e27b

File tree

5 files changed

+224
-0
lines changed

5 files changed

+224
-0
lines changed

app/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ android {
3838
}
3939
}
4040

41+
androidComponents {
42+
finalizeDsl { extension ->
43+
extension.sourceSets.getByName("benchmarkRelease").manifest.srcFile(
44+
"src/benchmarkRelease/AndroidManifest.xml",
45+
)
46+
}
47+
}
48+
4149
dependencies {
4250
implementation(projects.core.common)
4351
implementation(projects.core.analytics)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application>
5+
<activity
6+
android:name="com.yapp.orbit.benchmark.BenchmarkHostActivity"
7+
android:exported="true"
8+
android:label="@string/app_name"
9+
android:theme="@style/Theme.Orbit" />
10+
</application>
11+
</manifest>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.yapp.orbit.benchmark
2+
3+
import android.os.Bundle
4+
import androidx.activity.ComponentActivity
5+
import androidx.activity.compose.ReportDrawnWhen
6+
import androidx.activity.compose.setContent
7+
import androidx.compose.foundation.background
8+
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.material3.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.ui.Alignment
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.semantics.contentDescription
15+
import androidx.compose.ui.semantics.semantics
16+
import androidx.compose.ui.text.font.FontWeight
17+
import androidx.compose.ui.unit.sp
18+
import com.yapp.designsystem.theme.OrbitTheme
19+
20+
internal const val EXTRA_BENCHMARK_SCREEN = "benchmark_screen_key"
21+
internal const val BENCHMARK_SCREEN_ORBIT_PICKER = "orbit_picker"
22+
internal const val BENCHMARK_UNKNOWN_SCREEN_ROOT = "benchmark_unknown_screen"
23+
24+
class BenchmarkHostActivity : ComponentActivity() {
25+
override fun onCreate(savedInstanceState: Bundle?) {
26+
super.onCreate(savedInstanceState)
27+
val screenKey = intent?.getStringExtra(EXTRA_BENCHMARK_SCREEN)
28+
setContent {
29+
OrbitTheme {
30+
BenchmarkScreenContainer(screenKey)
31+
}
32+
}
33+
}
34+
}
35+
36+
@Composable
37+
private fun BenchmarkScreenContainer(screenKey: String?) {
38+
when (screenKey) {
39+
BENCHMARK_SCREEN_ORBIT_PICKER -> OrbitPickerBenchmarkScreen()
40+
else -> BenchmarkScreenMissing(screenKey)
41+
}
42+
}
43+
44+
@Composable
45+
private fun BenchmarkScreenMissing(requestedKey: String?) {
46+
ReportDrawnWhen { true }
47+
Box(
48+
modifier = Modifier
49+
.fillMaxSize()
50+
.background(OrbitTheme.colors.gray_900)
51+
.semantics { contentDescription = BENCHMARK_UNKNOWN_SCREEN_ROOT },
52+
contentAlignment = Alignment.Center,
53+
) {
54+
Text(
55+
text = "Benchmark screen '${requestedKey ?: "unknown"}' not registered.",
56+
color = OrbitTheme.colors.white,
57+
fontSize = 16.sp,
58+
fontWeight = FontWeight.SemiBold,
59+
)
60+
}
61+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.yapp.orbit.benchmark
2+
3+
import androidx.activity.compose.ReportDrawnWhen
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.foundation.layout.Column
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.runtime.Composable
11+
import androidx.compose.runtime.LaunchedEffect
12+
import androidx.compose.runtime.getValue
13+
import androidx.compose.runtime.mutableStateOf
14+
import androidx.compose.runtime.remember
15+
import androidx.compose.runtime.setValue
16+
import androidx.compose.ui.Alignment
17+
import androidx.compose.ui.Modifier
18+
import androidx.compose.ui.semantics.contentDescription
19+
import androidx.compose.ui.semantics.semantics
20+
import androidx.compose.ui.tooling.preview.Preview
21+
import androidx.compose.ui.unit.dp
22+
import com.yapp.designsystem.theme.OrbitTheme
23+
import com.yapp.ui.component.timepicker.OrbitPicker
24+
import java.time.LocalTime
25+
26+
internal const val ORBIT_PICKER_BENCHMARK_ROOT = "orbit_picker_root"
27+
28+
@Composable
29+
internal fun OrbitPickerBenchmarkScreen(
30+
modifier: Modifier = Modifier,
31+
initialTime: LocalTime = LocalTime.of(8, 30),
32+
) {
33+
var selectedTime by remember { mutableStateOf(initialTime) }
34+
var isDrawn by remember { mutableStateOf(false) }
35+
36+
ReportDrawnWhen { isDrawn }
37+
38+
LaunchedEffect(Unit) {
39+
isDrawn = true
40+
}
41+
42+
Box(
43+
modifier = modifier
44+
.fillMaxSize()
45+
.background(OrbitTheme.colors.gray_900)
46+
.semantics { contentDescription = ORBIT_PICKER_BENCHMARK_ROOT },
47+
contentAlignment = Alignment.Center,
48+
) {
49+
Column(
50+
horizontalAlignment = Alignment.CenterHorizontally,
51+
verticalArrangement = Arrangement.Center,
52+
modifier = Modifier.padding(horizontal = 24.dp),
53+
) {
54+
OrbitPicker(
55+
initialTime = selectedTime,
56+
onValueChange = { selectedTime = it },
57+
)
58+
}
59+
}
60+
}
61+
62+
@Preview
63+
@Composable
64+
private fun OrbitPickerBenchmarkPreview() {
65+
OrbitTheme {
66+
OrbitPickerBenchmarkScreen()
67+
}
68+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.dongchyeon.baselineprofile
2+
3+
import android.content.ComponentName
4+
import android.content.Intent
5+
import androidx.benchmark.macro.CompilationMode
6+
import androidx.benchmark.macro.FrameTimingMetric
7+
import androidx.benchmark.macro.StartupMode
8+
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
9+
import androidx.test.ext.junit.runners.AndroidJUnit4
10+
import androidx.test.filters.LargeTest
11+
import androidx.test.platform.app.InstrumentationRegistry
12+
import androidx.test.uiautomator.By
13+
import androidx.test.uiautomator.Until
14+
import org.junit.Rule
15+
import org.junit.Test
16+
import org.junit.runner.RunWith
17+
18+
@RunWith(AndroidJUnit4::class)
19+
@LargeTest
20+
class OrbitPickerBenchmarks {
21+
22+
@get:Rule
23+
val rule = MacrobenchmarkRule()
24+
25+
@Test
26+
fun orbitPickerScrollCompilationNone() = benchmark(CompilationMode.None())
27+
28+
@Test
29+
fun orbitPickerScrollCompilationBaselineProfile() = benchmark(CompilationMode.Partial())
30+
31+
private fun benchmark(compilationMode: CompilationMode) {
32+
val targetPackage = InstrumentationRegistry.getArguments().getString("targetAppId")
33+
?: throw IllegalStateException("targetAppId not passed as instrumentation runner arg")
34+
35+
rule.measureRepeated(
36+
packageName = targetPackage,
37+
metrics = listOf(FrameTimingMetric()),
38+
compilationMode = compilationMode,
39+
startupMode = StartupMode.COLD,
40+
iterations = 10,
41+
setupBlock = {
42+
killProcess()
43+
pressHome()
44+
},
45+
measureBlock = {
46+
val intent = Intent().apply {
47+
component = ComponentName(targetPackage, BENCHMARK_ACTIVITY_NAME)
48+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
49+
putExtra(BENCHMARK_SCREEN_EXTRA, ORBIT_PICKER_SCREEN_KEY)
50+
}
51+
52+
startActivityAndWait(intent)
53+
54+
device.wait(Until.hasObject(By.desc(ORBIT_PICKER_SEMANTICS)), 5_000)
55+
val picker = device.findObject(By.desc(ORBIT_PICKER_SEMANTICS))
56+
?: error("OrbitPicker root not found")
57+
58+
val bounds = picker.visibleBounds
59+
val x = bounds.centerX() + bounds.width() / 4
60+
val startY = bounds.centerY() + bounds.height() / 4
61+
val endY = bounds.centerY() - bounds.height() / 4
62+
63+
device.swipe(x, startY, x, endY, 30)
64+
device.waitForIdle()
65+
},
66+
)
67+
}
68+
69+
private companion object {
70+
private const val BENCHMARK_ACTIVITY_NAME =
71+
"com.yapp.orbit.benchmark.BenchmarkHostActivity"
72+
private const val BENCHMARK_SCREEN_EXTRA = "benchmark_screen_key"
73+
private const val ORBIT_PICKER_SCREEN_KEY = "orbit_picker"
74+
private const val ORBIT_PICKER_SEMANTICS = "orbit_picker_root"
75+
}
76+
}

0 commit comments

Comments
 (0)