Skip to content

Commit 9c8285a

Browse files
feat(profiling): replace useProfilingManager with enableLegacyProfiling (option 4)
ProfilingManager (Perfetto) is now always used on API 35+ — no opt-in required. enableLegacyProfiling (default: true) controls whether the legacy Debug-based profiler runs on sub-API-35 devices. Set to false to disable profiling on older devices entirely. This option will be removed in the next major release. - SentryOptions: remove useProfilingManager, add enableLegacyProfiling=true (@deprecated) - SentryAppStartProfilingOptions: same field/JSON key rename - AndroidOptionsInitializer: always use PerfettoContinuousProfiler on API 35+, fall back to AndroidContinuousProfiler when enableLegacyProfiling=true - SentryPerformanceProvider: skip legacy app-start profiling on API 35+ by API level check; also skip if enableLegacyProfiling=false on older devices - ManifestMetadataReader: rename manifest key to io.sentry.profiling.enable-legacy-profiling - Update tests and API surface accordingly Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
1 parent 24bcfed commit 9c8285a

11 files changed

Lines changed: 99 additions & 78 deletions

File tree

sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -340,27 +340,18 @@ private static void setupProfiler(
340340
final @NotNull SentryFrameMetricsCollector frameMetricsCollector =
341341
Objects.requireNonNull(
342342
options.getFrameMetricsCollector(), "options.getFrameMetricsCollector is required");
343-
if (options.isUseProfilingManager()) {
344-
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
345-
options.setContinuousProfiler(
346-
new PerfettoContinuousProfiler(
347-
options.getLogger(),
348-
frameMetricsCollector,
349-
() -> options.getExecutorService(),
350-
() ->
351-
new PerfettoProfiler(
352-
context.getApplicationContext(),
353-
options.getLogger(),
354-
options.getExecutorService())));
355-
} else {
356-
options
357-
.getLogger()
358-
.log(
359-
SentryLevel.WARNING,
360-
"useProfilingManager is enabled but requires API 35+. "
361-
+ "No profiling data will be collected.");
362-
}
363-
} else {
343+
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
344+
options.setContinuousProfiler(
345+
new PerfettoContinuousProfiler(
346+
options.getLogger(),
347+
frameMetricsCollector,
348+
() -> options.getExecutorService(),
349+
() ->
350+
new PerfettoProfiler(
351+
context.getApplicationContext(),
352+
options.getLogger(),
353+
options.getExecutorService())));
354+
} else if (options.isEnableLegacyProfiling()) {
364355
options.setContinuousProfiler(
365356
new AndroidContinuousProfiler(
366357
buildInfoProvider,
@@ -369,6 +360,13 @@ private static void setupProfiler(
369360
options.getProfilingTracesDirPath(),
370361
options.getProfilingTracesHz(),
371362
() -> options.getExecutorService()));
363+
} else {
364+
options
365+
.getLogger()
366+
.log(
367+
SentryLevel.WARNING,
368+
"enableLegacyProfiling is disabled and device is below API 35. "
369+
+ "No profiling data will be collected.");
372370
}
373371
}
374372
}

sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ final class ManifestMetadataReader {
109109

110110
static final String ENABLE_APP_START_PROFILING = "io.sentry.profiling.enable-app-start";
111111

112-
static final String USE_PROFILING_MANAGER = "io.sentry.profiling.use-profiling-manager";
112+
static final String ENABLE_LEGACY_PROFILING = "io.sentry.profiling.enable-legacy-profiling";
113113

114114
static final String ENABLE_SCOPE_PERSISTENCE = "io.sentry.enable-scope-persistence";
115115

@@ -505,8 +505,8 @@ static void applyMetadata(
505505
readBool(
506506
metadata, logger, ENABLE_APP_START_PROFILING, options.isEnableAppStartProfiling()));
507507

508-
options.setUseProfilingManager(
509-
readBool(metadata, logger, USE_PROFILING_MANAGER, options.isUseProfilingManager()));
508+
options.setEnableLegacyProfiling(
509+
readBool(metadata, logger, ENABLE_LEGACY_PROFILING, options.isEnableLegacyProfiling()));
510510

511511
options.setEnableScopePersistence(
512512
readBool(

sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,19 @@ private void launchAppStartProfiler(final @NotNull AppStartMetrics appStartMetri
129129
return;
130130
}
131131

132-
if (profilingOptions.isUseProfilingManager()) {
132+
if (buildInfoProvider.getSdkInfoVersion() >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM) {
133133
logger.log(
134134
SentryLevel.DEBUG,
135-
"useProfilingManager is enabled. Skipping legacy app-start profiling — "
136-
+ "ProfilingManager will be initialized after Sentry.init().");
135+
"Device is API 35+. Skipping legacy app-start profiling — "
136+
+ "Perfetto ProfilingManager will be initialized after Sentry.init().");
137+
return;
138+
}
139+
140+
if (!profilingOptions.isEnableLegacyProfiling()) {
141+
logger.log(
142+
SentryLevel.WARNING,
143+
"enableLegacyProfiling is disabled and device is below API 35. "
144+
+ "App start profiling will not start.");
137145
return;
138146
}
139147

sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,15 +378,22 @@ class AndroidOptionsInitializerTest {
378378

379379
@Config(sdk = [35])
380380
@Test
381-
fun `init with useProfilingManager on API 35+ sets PerfettoContinuousProfiler`() {
382-
fixture.initSut(configureOptions = { isUseProfilingManager = true })
381+
fun `init on API 35+ always sets PerfettoContinuousProfiler`() {
382+
fixture.initSut()
383383
assertTrue(fixture.sentryOptions.continuousProfiler is PerfettoContinuousProfiler)
384384
}
385385

386386
@Config(sdk = [34])
387387
@Test
388-
fun `init with useProfilingManager below API 35 noops profiler`() {
389-
fixture.initSut(configureOptions = { isUseProfilingManager = true })
388+
fun `init below API 35 with enableLegacyProfiling true sets AndroidContinuousProfiler`() {
389+
fixture.initSut(configureOptions = { isEnableLegacyProfiling = true })
390+
assertTrue(fixture.sentryOptions.continuousProfiler is AndroidContinuousProfiler)
391+
}
392+
393+
@Config(sdk = [34])
394+
@Test
395+
fun `init below API 35 with enableLegacyProfiling false noops profiler`() {
396+
fixture.initSut(configureOptions = { isEnableLegacyProfiling = false })
390397
assertTrue(fixture.sentryOptions.continuousProfiler is NoOpContinuousProfiler)
391398
}
392399

sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,28 +1495,28 @@ class ManifestMetadataReaderTest {
14951495
}
14961496

14971497
@Test
1498-
fun `applyMetadata reads useProfilingManager flag to options`() {
1498+
fun `applyMetadata reads enableLegacyProfiling flag to options`() {
14991499
// Arrange
1500-
val bundle = bundleOf(ManifestMetadataReader.USE_PROFILING_MANAGER to true)
1500+
val bundle = bundleOf(ManifestMetadataReader.ENABLE_LEGACY_PROFILING to false)
15011501
val context = fixture.getContext(metaData = bundle)
15021502

15031503
// Act
15041504
ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)
15051505

15061506
// Assert
1507-
assertTrue(fixture.options.isUseProfilingManager)
1507+
assertFalse(fixture.options.isEnableLegacyProfiling)
15081508
}
15091509

15101510
@Test
1511-
fun `applyMetadata reads useProfilingManager flag to options and keeps default if not found`() {
1511+
fun `applyMetadata reads enableLegacyProfiling flag to options and keeps default if not found`() {
15121512
// Arrange
15131513
val context = fixture.getContext()
15141514

15151515
// Act
15161516
ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)
15171517

15181518
// Assert
1519-
assertFalse(fixture.options.isUseProfilingManager)
1519+
assertTrue(fixture.options.isEnableLegacyProfiling)
15201520
}
15211521

15221522
@Test

sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,6 @@
164164
<meta-data
165165
android:name="io.sentry.traces.profiling.start-on-app-start"
166166
android:value="false" />
167-
<!-- Enable ProfilingManager (Perfetto) on API 35+ -->
168-
<meta-data
169-
android:name="io.sentry.profiling.use-profiling-manager"
170-
android:value="true" />
171167

172168
<!-- how to disable the Activity auto instrumentation for tracing-->
173169
<!-- <meta-data android:name="io.sentry.traces.activity.enable" android:value="false" />-->

sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/ProfilingActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ProfilingActivity : ComponentActivity() {
4545
private fun ProfilingScreen() {
4646
val context = LocalContext.current
4747
val options = remember { Sentry.getCurrentScopes().options }
48-
val isPerfetto = remember { options.isUseProfilingManager && Build.VERSION.SDK_INT >= 35 }
48+
val isPerfetto = remember { Build.VERSION.SDK_INT >= 35 }
4949
val isContinuousEnabled = remember { options.isContinuousProfilingEnabled }
5050

5151
var showProgress by remember { mutableStateOf(false) }
@@ -65,7 +65,7 @@ class ProfilingActivity : ComponentActivity() {
6565
) {
6666
Text(text = statusText, fontWeight = FontWeight.Bold)
6767

68-
Text("profiling.use-profiling-manager: ${options.isUseProfilingManager}")
68+
Text("profiling.enable-legacy-profiling: ${options.isEnableLegacyProfiling}")
6969
Text("Build.VERSION.SDK_INT: ${Build.VERSION.SDK_INT}")
7070
Text("traces.profiling.session-sample-rate: ${options.profileSessionSampleRate}")
7171

sentry/api/sentry.api

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,7 +2830,7 @@ public final class io/sentry/SentryAppStartProfilingOptions : io/sentry/JsonSeri
28302830
public fun isProfilingEnabled ()Z
28312831
public fun isStartProfilerOnAppStart ()Z
28322832
public fun isTraceSampled ()Z
2833-
public fun isUseProfilingManager ()Z
2833+
public fun isEnableLegacyProfiling ()Z
28342834
public fun serialize (Lio/sentry/ObjectWriter;Lio/sentry/ILogger;)V
28352835
public fun setContinuousProfileSampled (Z)V
28362836
public fun setContinuousProfilingEnabled (Z)V
@@ -2845,7 +2845,7 @@ public final class io/sentry/SentryAppStartProfilingOptions : io/sentry/JsonSeri
28452845
public fun setTraceSampleRate (Ljava/lang/Double;)V
28462846
public fun setTraceSampled (Z)V
28472847
public fun setUnknown (Ljava/util/Map;)V
2848-
public fun setUseProfilingManager (Z)V
2848+
public fun setEnableLegacyProfiling (Z)V
28492849
}
28502850

28512851
public final class io/sentry/SentryAppStartProfilingOptions$Deserializer : io/sentry/JsonDeserializer {
@@ -2867,7 +2867,7 @@ public final class io/sentry/SentryAppStartProfilingOptions$JsonKeys {
28672867
public static final field PROFILING_TRACES_HZ Ljava/lang/String;
28682868
public static final field TRACE_SAMPLED Ljava/lang/String;
28692869
public static final field TRACE_SAMPLE_RATE Ljava/lang/String;
2870-
public static final field USE_PROFILING_MANAGER Ljava/lang/String;
2870+
public static final field ENABLE_LEGACY_PROFILING Ljava/lang/String;
28712871
public fun <init> ()V
28722872
}
28732873

@@ -3748,7 +3748,7 @@ public class io/sentry/SentryOptions {
37483748
public fun isTraceOptionsRequests ()Z
37493749
public fun isTraceSampling ()Z
37503750
public fun isTracingEnabled ()Z
3751-
public fun isUseProfilingManager ()Z
3751+
public fun isEnableLegacyProfiling ()Z
37523752
public fun merge (Lio/sentry/ExternalOptions;)V
37533753
public fun setAttachServerName (Z)V
37543754
public fun setAttachStacktrace (Z)V
@@ -3875,7 +3875,7 @@ public class io/sentry/SentryOptions {
38753875
public fun setTransactionProfiler (Lio/sentry/ITransactionProfiler;)V
38763876
public fun setTransportFactory (Lio/sentry/ITransportFactory;)V
38773877
public fun setTransportGate (Lio/sentry/transport/ITransportGate;)V
3878-
public fun setUseProfilingManager (Z)V
3878+
public fun setEnableLegacyProfiling (Z)V
38793879
public fun setVersionDetector (Lio/sentry/IVersionDetector;)V
38803880
public fun setViewHierarchyExporters (Ljava/util/List;)V
38813881
}

sentry/src/main/java/io/sentry/SentryAppStartProfilingOptions.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public final class SentryAppStartProfilingOptions implements JsonUnknown, JsonSe
2424
boolean continuousProfileSampled;
2525
boolean isEnableAppStartProfiling;
2626
boolean isStartProfilerOnAppStart;
27-
boolean useProfilingManager;
27+
boolean enableLegacyProfiling;
2828
@NotNull ProfileLifecycle profileLifecycle;
2929

3030
private @Nullable Map<String, Object> unknown;
@@ -43,7 +43,7 @@ public SentryAppStartProfilingOptions() {
4343
profilingTracesHz = 0;
4444
isEnableAppStartProfiling = true;
4545
isStartProfilerOnAppStart = false;
46-
useProfilingManager = false;
46+
enableLegacyProfiling = true;
4747
}
4848

4949
SentryAppStartProfilingOptions(
@@ -64,7 +64,7 @@ public SentryAppStartProfilingOptions() {
6464
profilingTracesHz = options.getProfilingTracesHz();
6565
isEnableAppStartProfiling = options.isEnableAppStartProfiling();
6666
isStartProfilerOnAppStart = options.isStartProfilerOnAppStart();
67-
useProfilingManager = options.isUseProfilingManager();
67+
enableLegacyProfiling = options.isEnableLegacyProfiling();
6868
}
6969

7070
public void setProfileSampled(final boolean profileSampled) {
@@ -163,12 +163,14 @@ public boolean isStartProfilerOnAppStart() {
163163
return isStartProfilerOnAppStart;
164164
}
165165

166-
public void setUseProfilingManager(final boolean useProfilingManager) {
167-
this.useProfilingManager = useProfilingManager;
166+
@Deprecated
167+
public void setEnableLegacyProfiling(final boolean enableLegacyProfiling) {
168+
this.enableLegacyProfiling = enableLegacyProfiling;
168169
}
169170

170-
public boolean isUseProfilingManager() {
171-
return useProfilingManager;
171+
@Deprecated
172+
public boolean isEnableLegacyProfiling() {
173+
return enableLegacyProfiling;
172174
}
173175

174176
// JsonSerializable
@@ -186,7 +188,7 @@ public static final class JsonKeys {
186188
public static final String PROFILING_TRACES_HZ = "profiling_traces_hz";
187189
public static final String IS_ENABLE_APP_START_PROFILING = "is_enable_app_start_profiling";
188190
public static final String IS_START_PROFILER_ON_APP_START = "is_start_profiler_on_app_start";
189-
public static final String USE_PROFILING_MANAGER = "use_profiling_manager";
191+
public static final String ENABLE_LEGACY_PROFILING = "enable_legacy_profiling";
190192
}
191193

192194
@Override
@@ -207,7 +209,7 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
207209
writer.name(JsonKeys.PROFILING_TRACES_HZ).value(logger, profilingTracesHz);
208210
writer.name(JsonKeys.IS_ENABLE_APP_START_PROFILING).value(logger, isEnableAppStartProfiling);
209211
writer.name(JsonKeys.IS_START_PROFILER_ON_APP_START).value(logger, isStartProfilerOnAppStart);
210-
writer.name(JsonKeys.USE_PROFILING_MANAGER).value(logger, useProfilingManager);
212+
writer.name(JsonKeys.ENABLE_LEGACY_PROFILING).value(logger, enableLegacyProfiling);
211213

212214
if (unknown != null) {
213215
for (String key : unknown.keySet()) {
@@ -321,10 +323,10 @@ public static final class Deserializer
321323
options.isStartProfilerOnAppStart = isStartProfilerOnAppStart;
322324
}
323325
break;
324-
case JsonKeys.USE_PROFILING_MANAGER:
325-
@Nullable Boolean useProfilingManager = reader.nextBooleanOrNull();
326-
if (useProfilingManager != null) {
327-
options.useProfilingManager = useProfilingManager;
326+
case JsonKeys.ENABLE_LEGACY_PROFILING:
327+
@Nullable Boolean enableLegacyProfiling = reader.nextBooleanOrNull();
328+
if (enableLegacyProfiling != null) {
329+
options.enableLegacyProfiling = enableLegacyProfiling;
328330
}
329331
break;
330332
default:

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -646,11 +646,14 @@ public class SentryOptions {
646646
private boolean startProfilerOnAppStart = false;
647647

648648
/**
649-
* When true, the SDK uses Android's {@code ProfilingManager} (Perfetto-based stack sampling) on
650-
* API 35+ devices. On older devices where ProfilingManager is not available, no profiling data is
651-
* collected — the legacy {@code Debug}-based profiler is not used as a fallback.
649+
* When false, the legacy {@code Debug}-based profiler is disabled on API < 35 devices. On API
650+
* 35+ devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used
651+
* regardless of this setting. This option will be removed in the next major release.
652+
*
653+
* @deprecated Legacy profiling will be removed in the next major release.
652654
*/
653-
private boolean useProfilingManager = false;
655+
@Deprecated
656+
private boolean enableLegacyProfiling = true;
654657

655658
/**
656659
* Controls the deadline timeout in milliseconds for automatic transactions. When set to a
@@ -2244,22 +2247,29 @@ public void setStartProfilerOnAppStart(final boolean startProfilerOnAppStart) {
22442247
}
22452248

22462249
/**
2247-
* Whether to use Android's ProfilingManager (Perfetto) for profiling on Android 35+.
2250+
* Whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. On API 35+,
2251+
* Android's {@code ProfilingManager} (Perfetto) is always used regardless of this setting.
22482252
*
2249-
* @return true if ProfilingManager-based profiling is enabled.
2253+
* @return true if legacy profiling is enabled (default).
2254+
* @deprecated Legacy profiling will be removed in the next major release.
22502255
*/
2251-
public boolean isUseProfilingManager() {
2252-
return useProfilingManager;
2256+
@Deprecated
2257+
public boolean isEnableLegacyProfiling() {
2258+
return enableLegacyProfiling;
22532259
}
22542260

22552261
/**
2256-
* Set whether to use Android's ProfilingManager (Perfetto) for profiling on Android 35+. On
2257-
* devices below API 35 where ProfilingManager is not available, no profiling data is collected.
2262+
* Set whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. Set to
2263+
* {@code false} to disable profiling on devices below API 35. On API 35+ devices, Android's
2264+
* {@code ProfilingManager} (Perfetto) is always used and this setting has no effect. This option
2265+
* will be removed in the next major release.
22582266
*
2259-
* @param useProfilingManager true to use ProfilingManager-based profiling.
2267+
* @param enableLegacyProfiling false to disable legacy profiling on API < 35.
2268+
* @deprecated Legacy profiling will be removed in the next major release.
22602269
*/
2261-
public void setUseProfilingManager(final boolean useProfilingManager) {
2262-
this.useProfilingManager = useProfilingManager;
2270+
@Deprecated
2271+
public void setEnableLegacyProfiling(final boolean enableLegacyProfiling) {
2272+
this.enableLegacyProfiling = enableLegacyProfiling;
22632273
}
22642274

22652275
public long getDeadlineTimeout() {

0 commit comments

Comments
 (0)