1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.benchmark
18 
19 import android.os.Build
20 
21 /**
22  * Profiler configuration object.
23  *
24  * Will eventually allow further configuration, e.g. sampling frequency.
25  */
26 @ExperimentalBenchmarkConfigApi
27 sealed class ProfilerConfig(internal val profiler: Profiler) {
28     class StackSampling() :
29         ProfilerConfig(
30             profiler =
31                 if (Build.VERSION.SDK_INT >= 29) {
32                     StackSamplingSimpleperf
33                 } else {
34                     StackSamplingLegacy
35                 }
36         )
37 
38     class MethodTracing() : ProfilerConfig(profiler = androidx.benchmark.MethodTracing) {
39         companion object {
40             /**
41              * This value is true if method tracing affects future performance measurement within
42              * the process on the current device.
43              *
44              * This is determined both by the OS version and ART mainline module version (if
45              * present).
46              *
47              * If this value is true, no measurements can be made by microbenchmark after a method
48              * trace completes, and further benchmarks will throw rather than capturing invalid
49              * metrics until the next process restart.
50              *
51              * You can use `assumeFalse(MethodTracing.affectsMeasurementOnThisDevice)` to skip tests
52              * that use method tracing, configure your profiler based on this flag, or select a
53              * different device to avoid runtime crashes.
54              *
55              * Note that by default, microbenchmarks enable method tracing only when this value is
56              * false.
57              *
58              * Method tracing is always performed after any measurement phases, so single method
59              * benchmark runs are not affected - throwing will happen starting with the 2nd
60              * benchmark in a suite (process invocation).
61              */
62             @Suppress("GetterSetterNames")
63             @JvmField
64             val AFFECTS_MEASUREMENTS_ON_THIS_DEVICE: Boolean =
65                 DeviceInfo.methodTracingAffectsMeasurements
66         }
67     }
68 
69     // used for tests
70     internal class StackSamplingLegacy() : ProfilerConfig(profiler = StackSamplingLegacy)
71 }
72