diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api
index 82e556a87d..dd4cfdf353 100644
--- a/sentry-android-core/api/sentry-android-core.api
+++ b/sentry-android-core/api/sentry-android-core.api
@@ -41,7 +41,6 @@ public class io/sentry/android/core/AndroidContinuousProfiler : io/sentry/IConti
public fun close ()V
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
public fun isRunning ()Z
- public fun setScopes (Lio/sentry/IScopes;)V
public fun start ()V
public fun stop ()V
}
diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java
index 12d2129383..0536dcabc7 100644
--- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java
+++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java
@@ -9,8 +9,10 @@
import io.sentry.ILogger;
import io.sentry.IScopes;
import io.sentry.ISentryExecutorService;
+import io.sentry.NoOpScopes;
import io.sentry.PerformanceCollectionData;
import io.sentry.ProfileChunk;
+import io.sentry.Sentry;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
@@ -88,12 +90,14 @@ private void init() {
logger);
}
- public synchronized void setScopes(final @NotNull IScopes scopes) {
- this.scopes = scopes;
- this.performanceCollector = scopes.getOptions().getCompositePerformanceCollector();
- }
-
public synchronized void start() {
+ if ((scopes == null || scopes != NoOpScopes.getInstance())
+ && Sentry.getCurrentScopes() != NoOpScopes.getInstance()) {
+ this.scopes = Sentry.getCurrentScopes();
+ this.performanceCollector =
+ Sentry.getCurrentScopes().getOptions().getCompositePerformanceCollector();
+ }
+
// Debug.startMethodTracingSampling() is only available since Lollipop, but Android Profiler
// causes crashes on api 21 -> https://github.com/getsentry/sentry-java/issues/3392
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP_MR1) return;
diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidContinuousProfilerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidContinuousProfilerTest.kt
index 6e532f8f2b..70ed75186c 100644
--- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidContinuousProfilerTest.kt
+++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidContinuousProfilerTest.kt
@@ -11,6 +11,7 @@ import io.sentry.IScopes
import io.sentry.ISentryExecutorService
import io.sentry.MemoryCollectionData
import io.sentry.PerformanceCollectionData
+import io.sentry.Sentry
import io.sentry.SentryLevel
import io.sentry.SentryNanotimeDate
import io.sentry.SentryTracer
@@ -80,7 +81,7 @@ class AndroidContinuousProfilerTest {
options.profilingTracesDirPath,
options.profilingTracesHz,
options.executorService
- ).also { it.setScopes(scopes) }
+ )
}
}
@@ -118,6 +119,8 @@ class AndroidContinuousProfilerTest {
// Profiler doesn't start if the folder doesn't exists.
// Usually it's generated when calling Sentry.init, but for tests we can create it manually.
File(fixture.options.profilingTracesDirPath!!).mkdirs()
+
+ Sentry.setCurrentScopes(fixture.scopes)
}
@AfterTest
diff --git a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
index ac85411017..fa070ac644 100644
--- a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
+++ b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
@@ -110,7 +110,7 @@
-
+
diff --git a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java
index a4a1c5397a..572c4cdba7 100644
--- a/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java
+++ b/sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java
@@ -2,12 +2,14 @@
import android.app.Application;
import android.os.StrictMode;
+import io.sentry.Sentry;
/** Apps. main Application. */
public class MyApplication extends Application {
@Override
public void onCreate() {
+ Sentry.startProfiler();
strictMode();
super.onCreate();
diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api
index 9738b4ea23..f3a84217b5 100644
--- a/sentry/api/sentry.api
+++ b/sentry/api/sentry.api
@@ -619,8 +619,10 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -684,8 +686,10 @@ public final class io/sentry/HubScopesWrapper : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -714,7 +718,6 @@ public abstract interface class io/sentry/IContinuousProfiler {
public abstract fun close ()V
public abstract fun getProfilerId ()Lio/sentry/protocol/SentryId;
public abstract fun isRunning ()Z
- public abstract fun setScopes (Lio/sentry/IScopes;)V
public abstract fun start ()V
public abstract fun stop ()V
}
@@ -921,11 +924,13 @@ public abstract interface class io/sentry/IScopes {
public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public abstract fun setTransaction (Ljava/lang/String;)V
public abstract fun setUser (Lio/sentry/protocol/User;)V
+ public abstract fun startProfiler ()V
public abstract fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public abstract fun stopProfiler ()V
public abstract fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public abstract fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -1395,7 +1400,6 @@ public final class io/sentry/NoOpContinuousProfiler : io/sentry/IContinuousProfi
public static fun getInstance ()Lio/sentry/NoOpContinuousProfiler;
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
public fun isRunning ()Z
- public fun setScopes (Lio/sentry/IScopes;)V
public fun start ()V
public fun stop ()V
}
@@ -1465,8 +1469,10 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -1625,8 +1631,10 @@ public final class io/sentry/NoOpScopes : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -2278,8 +2286,10 @@ public final class io/sentry/Scopes : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -2343,8 +2353,10 @@ public final class io/sentry/ScopesAdapter : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
+ public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
@@ -2447,12 +2459,14 @@ public final class io/sentry/Sentry {
public static fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public static fun setTransaction (Ljava/lang/String;)V
public static fun setUser (Lio/sentry/protocol/User;)V
+ public static fun startProfiler ()V
public static fun startSession ()V
public static fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
public static fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
+ public static fun stopProfiler ()V
public static fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public static fun withScope (Lio/sentry/ScopeCallback;)V
}
diff --git a/sentry/src/main/java/io/sentry/HubAdapter.java b/sentry/src/main/java/io/sentry/HubAdapter.java
index d71f5b10ba..537bcdf104 100644
--- a/sentry/src/main/java/io/sentry/HubAdapter.java
+++ b/sentry/src/main/java/io/sentry/HubAdapter.java
@@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return Sentry.startTransaction(transactionContext, transactionOptions);
}
+ @Override
+ public void startProfiler() {
+ Sentry.startProfiler();
+ }
+
+ @Override
+ public void stopProfiler() {
+ Sentry.stopProfiler();
+ }
+
@Override
public @NotNull SentryId captureProfileChunk(
final @NotNull ProfileChunk profilingContinuousData) {
diff --git a/sentry/src/main/java/io/sentry/HubScopesWrapper.java b/sentry/src/main/java/io/sentry/HubScopesWrapper.java
index 31c2270431..d6755c2c41 100644
--- a/sentry/src/main/java/io/sentry/HubScopesWrapper.java
+++ b/sentry/src/main/java/io/sentry/HubScopesWrapper.java
@@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return scopes.startTransaction(transactionContext, transactionOptions);
}
+ @Override
+ public void startProfiler() {
+ scopes.startProfiler();
+ }
+
+ @Override
+ public void stopProfiler() {
+ scopes.stopProfiler();
+ }
+
@ApiStatus.Internal
@Override
public void setSpanContext(
diff --git a/sentry/src/main/java/io/sentry/IContinuousProfiler.java b/sentry/src/main/java/io/sentry/IContinuousProfiler.java
index 3fe19f614b..14ce41a815 100644
--- a/sentry/src/main/java/io/sentry/IContinuousProfiler.java
+++ b/sentry/src/main/java/io/sentry/IContinuousProfiler.java
@@ -13,8 +13,6 @@ public interface IContinuousProfiler {
void stop();
- void setScopes(final @NotNull IScopes scopes);
-
/** Cancel the profiler and stops it. Used on SDK close. */
void close();
diff --git a/sentry/src/main/java/io/sentry/IScopes.java b/sentry/src/main/java/io/sentry/IScopes.java
index 14b8753b28..59a577f04b 100644
--- a/sentry/src/main/java/io/sentry/IScopes.java
+++ b/sentry/src/main/java/io/sentry/IScopes.java
@@ -592,6 +592,10 @@ ITransaction startTransaction(
final @NotNull TransactionContext transactionContext,
final @NotNull TransactionOptions transactionOptions);
+ void startProfiler();
+
+ void stopProfiler();
+
/**
* Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine
* in which trace the exception has been thrown in framework integrations.
diff --git a/sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java b/sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java
index 0ae5d6d81b..4ccf7cc681 100644
--- a/sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java
+++ b/sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java
@@ -19,9 +19,6 @@ public void start() {}
@Override
public void stop() {}
- @Override
- public void setScopes(@NotNull IScopes scopes) {}
-
@Override
public boolean isRunning() {
return false;
diff --git a/sentry/src/main/java/io/sentry/NoOpHub.java b/sentry/src/main/java/io/sentry/NoOpHub.java
index a304619b27..925f1e64ee 100644
--- a/sentry/src/main/java/io/sentry/NoOpHub.java
+++ b/sentry/src/main/java/io/sentry/NoOpHub.java
@@ -243,6 +243,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
return NoOpTransaction.getInstance();
}
+ @Override
+ public void startProfiler() {}
+
+ @Override
+ public void stopProfiler() {}
+
@Override
public void setSpanContext(
final @NotNull Throwable throwable,
diff --git a/sentry/src/main/java/io/sentry/NoOpScopes.java b/sentry/src/main/java/io/sentry/NoOpScopes.java
index 9ec3db2a62..11bae042b0 100644
--- a/sentry/src/main/java/io/sentry/NoOpScopes.java
+++ b/sentry/src/main/java/io/sentry/NoOpScopes.java
@@ -238,6 +238,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
return NoOpTransaction.getInstance();
}
+ @Override
+ public void startProfiler() {}
+
+ @Override
+ public void stopProfiler() {}
+
@Override
public void setSpanContext(
final @NotNull Throwable throwable,
diff --git a/sentry/src/main/java/io/sentry/Scopes.java b/sentry/src/main/java/io/sentry/Scopes.java
index 33d7f65d60..86f0f5f8bc 100644
--- a/sentry/src/main/java/io/sentry/Scopes.java
+++ b/sentry/src/main/java/io/sentry/Scopes.java
@@ -923,6 +923,34 @@ public void flush(long timeoutMillis) {
return transaction;
}
+ @Override
+ public void startProfiler() {
+ if (getOptions().isContinuousProfilingEnabled()) {
+ getOptions().getLogger().log(SentryLevel.DEBUG, "Started continuous Profiling.");
+ getOptions().getContinuousProfiler().start();
+ } else {
+ getOptions()
+ .getLogger()
+ .log(
+ SentryLevel.WARNING,
+ "Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
+ }
+ }
+
+ @Override
+ public void stopProfiler() {
+ if (getOptions().isContinuousProfilingEnabled()) {
+ getOptions().getLogger().log(SentryLevel.DEBUG, "Stopped continuous Profiling.");
+ getOptions().getContinuousProfiler().stop();
+ } else {
+ getOptions()
+ .getLogger()
+ .log(
+ SentryLevel.WARNING,
+ "Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
+ }
+ }
+
@Override
@ApiStatus.Internal
public void setSpanContext(
diff --git a/sentry/src/main/java/io/sentry/ScopesAdapter.java b/sentry/src/main/java/io/sentry/ScopesAdapter.java
index 8da3c4f615..9944a87a0a 100644
--- a/sentry/src/main/java/io/sentry/ScopesAdapter.java
+++ b/sentry/src/main/java/io/sentry/ScopesAdapter.java
@@ -280,6 +280,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return Sentry.startTransaction(transactionContext, transactionOptions);
}
+ @Override
+ public void startProfiler() {
+ Sentry.startProfiler();
+ }
+
+ @Override
+ public void stopProfiler() {
+ Sentry.stopProfiler();
+ }
+
@ApiStatus.Internal
@Override
public void setSpanContext(
diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java
index 7a35720e2d..3c30597b92 100644
--- a/sentry/src/main/java/io/sentry/Sentry.java
+++ b/sentry/src/main/java/io/sentry/Sentry.java
@@ -1049,6 +1049,16 @@ public static void endSession() {
return getCurrentScopes().startTransaction(transactionContext, transactionOptions);
}
+ /** Starts the continuous profiler, if enabled. */
+ public static void startProfiler() {
+ getCurrentScopes().startProfiler();
+ }
+
+ /** Starts the continuous profiler, if enabled. */
+ public static void stopProfiler() {
+ getCurrentScopes().stopProfiler();
+ }
+
/**
* Gets the current active transaction or span.
*
diff --git a/sentry/src/test/java/io/sentry/HubAdapterTest.kt b/sentry/src/test/java/io/sentry/HubAdapterTest.kt
index b48ae79703..310c153709 100644
--- a/sentry/src/test/java/io/sentry/HubAdapterTest.kt
+++ b/sentry/src/test/java/io/sentry/HubAdapterTest.kt
@@ -265,4 +265,14 @@ class HubAdapterTest {
HubAdapter.getInstance().reportFullyDisplayed()
verify(scopes).reportFullyDisplayed()
}
+
+ @Test fun `startProfiler calls Hub`() {
+ HubAdapter.getInstance().startProfiler()
+ verify(scopes).startProfiler()
+ }
+
+ @Test fun `stopProfiler calls Hub`() {
+ HubAdapter.getInstance().stopProfiler()
+ verify(scopes).stopProfiler()
+ }
}
diff --git a/sentry/src/test/java/io/sentry/NoOpHubTest.kt b/sentry/src/test/java/io/sentry/NoOpHubTest.kt
index fbd6e4c41b..e0eb08ded0 100644
--- a/sentry/src/test/java/io/sentry/NoOpHubTest.kt
+++ b/sentry/src/test/java/io/sentry/NoOpHubTest.kt
@@ -115,4 +115,10 @@ class NoOpHubTest {
sut.withScope(scopeCallback)
verify(scopeCallback).run(NoOpScope.getInstance())
}
+
+ @Test
+ fun `startProfiler doesnt throw`() = sut.startProfiler()
+
+ @Test
+ fun `stopProfiler doesnt throw`() = sut.stopProfiler()
}
diff --git a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt
index d30b653456..9c7418c6b5 100644
--- a/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt
+++ b/sentry/src/test/java/io/sentry/ScopesAdapterTest.kt
@@ -265,4 +265,14 @@ class ScopesAdapterTest {
ScopesAdapter.getInstance().reportFullyDisplayed()
verify(scopes).reportFullyDisplayed()
}
+
+ @Test fun `startProfiler calls Scopes`() {
+ ScopesAdapter.getInstance().startProfiler()
+ verify(scopes).startProfiler()
+ }
+
+ @Test fun `stopProfiler calls Scopes`() {
+ ScopesAdapter.getInstance().stopProfiler()
+ verify(scopes).stopProfiler()
+ }
}
diff --git a/sentry/src/test/java/io/sentry/ScopesTest.kt b/sentry/src/test/java/io/sentry/ScopesTest.kt
index 39b03d7ad2..68a1fee5d6 100644
--- a/sentry/src/test/java/io/sentry/ScopesTest.kt
+++ b/sentry/src/test/java/io/sentry/ScopesTest.kt
@@ -2160,6 +2160,56 @@ class ScopesTest {
assertEquals("other.span.origin", transaction.spanContext.origin)
}
+ @Test
+ fun `startProfiler starts the continuous profiler`() {
+ val profiler = mock()
+ val scopes = generateScopes {
+ it.setContinuousProfiler(profiler)
+ }
+ scopes.startProfiler()
+ verify(profiler).start()
+ }
+
+ @Test
+ fun `stopProfiler stops the continuous profiler`() {
+ val profiler = mock()
+ val scopes = generateScopes {
+ it.setContinuousProfiler(profiler)
+ }
+ scopes.stopProfiler()
+ verify(profiler).stop()
+ }
+
+ @Test
+ fun `startProfiler logs instructions if continuous profiling is disabled`() {
+ val profiler = mock()
+ val logger = mock()
+ val scopes = generateScopes {
+ it.setContinuousProfiler(profiler)
+ it.profilesSampleRate = 1.0
+ it.setLogger(logger)
+ it.isDebug = true
+ }
+ scopes.startProfiler()
+ verify(profiler, never()).start()
+ verify(logger).log(eq(SentryLevel.WARNING), eq("Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it."))
+ }
+
+ @Test
+ fun `stopProfiler logs instructions if continuous profiling is disabled`() {
+ val profiler = mock()
+ val logger = mock()
+ val scopes = generateScopes {
+ it.setContinuousProfiler(profiler)
+ it.profilesSampleRate = 1.0
+ it.setLogger(logger)
+ it.isDebug = true
+ }
+ scopes.stopProfiler()
+ verify(profiler, never()).stop()
+ verify(logger).log(eq(SentryLevel.WARNING), eq("Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it."))
+ }
+
private val dsnTest = "https://key@sentry.io/proj"
private fun generateScopes(optionsConfiguration: Sentry.OptionsConfiguration? = null): IScopes {
diff --git a/sentry/src/test/java/io/sentry/SentryTest.kt b/sentry/src/test/java/io/sentry/SentryTest.kt
index 3f39b29c01..6f7cd427da 100644
--- a/sentry/src/test/java/io/sentry/SentryTest.kt
+++ b/sentry/src/test/java/io/sentry/SentryTest.kt
@@ -1277,6 +1277,52 @@ class SentryTest {
assertNotSame(s1, s2)
}
+ @Test
+ fun `startProfiler starts the continuous profiler`() {
+ val profiler = mock()
+ Sentry.init {
+ it.dsn = dsn
+ it.setContinuousProfiler(profiler)
+ }
+ Sentry.startProfiler()
+ verify(profiler).start()
+ }
+
+ @Test
+ fun `startProfiler is ignored when continuous profiling is disabled`() {
+ val profiler = mock()
+ Sentry.init {
+ it.dsn = dsn
+ it.setContinuousProfiler(profiler)
+ it.profilesSampleRate = 1.0
+ }
+ Sentry.startProfiler()
+ verify(profiler, never()).start()
+ }
+
+ @Test
+ fun `stopProfiler stops the continuous profiler`() {
+ val profiler = mock()
+ Sentry.init {
+ it.dsn = dsn
+ it.setContinuousProfiler(profiler)
+ }
+ Sentry.stopProfiler()
+ verify(profiler).stop()
+ }
+
+ @Test
+ fun `stopProfiler is ignored when continuous profiling is disabled`() {
+ val profiler = mock()
+ Sentry.init {
+ it.dsn = dsn
+ it.setContinuousProfiler(profiler)
+ it.profilesSampleRate = 1.0
+ }
+ Sentry.stopProfiler()
+ verify(profiler, never()).stop()
+ }
+
private class InMemoryOptionsObserver : IOptionsObserver {
var release: String? = null
private set