Skip to content

Commit

Permalink
Merge fd99cb6 into f50fb16
Browse files Browse the repository at this point in the history
  • Loading branch information
markushi committed Oct 20, 2022
2 parents f50fb16 + fd99cb6 commit a3665da
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- Profile envelopes are sent directly from profiler ([#2298](https://github.com/getsentry/sentry-java/pull/2298))
- Add support for using Encoder with logback.SentryAppender ([#2246](https://github.com/getsentry/sentry-java/pull/2246))
- Report Startup Crashes ([#2277](https://github.com/getsentry/sentry-java/pull/2277))
- Add option to enable or disable Activity Frames Tracker ([#2314](https://github.com/getsentry/sentry-java/pull/2314))

### Dependencies

Expand Down
21 changes: 19 additions & 2 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
public final class io/sentry/android/core/ActivityFramesTracker {
public final class io/sentry/android/core/ActivityFramesTracker : io/sentry/android/core/IActivityFramesTracker {
public fun <init> (Lio/sentry/android/core/LoadClass;)V
public fun <init> (Lio/sentry/android/core/LoadClass;Lio/sentry/ILogger;)V
public fun <init> (Lio/sentry/android/core/LoadClass;Lio/sentry/ILogger;Lio/sentry/android/core/MainLooperHandler;)V
Expand All @@ -9,7 +9,7 @@ public final class io/sentry/android/core/ActivityFramesTracker {
}

public final class io/sentry/android/core/ActivityLifecycleIntegration : android/app/Application$ActivityLifecycleCallbacks, io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/app/Application;Lio/sentry/android/core/BuildInfoProvider;Lio/sentry/android/core/ActivityFramesTracker;)V
public fun <init> (Landroid/app/Application;Lio/sentry/android/core/BuildInfoProvider;Lio/sentry/android/core/IActivityFramesTracker;)V
public fun close ()V
public fun onActivityCreated (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityDestroyed (Landroid/app/Activity;)V
Expand Down Expand Up @@ -79,6 +79,13 @@ public abstract class io/sentry/android/core/EnvelopeFileObserverIntegration : i
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
}

public abstract interface class io/sentry/android/core/IActivityFramesTracker {
public abstract fun addActivity (Landroid/app/Activity;)V
public abstract fun setMetrics (Landroid/app/Activity;Lio/sentry/protocol/SentryId;)V
public abstract fun stop ()V
public abstract fun takeMetrics (Lio/sentry/protocol/SentryId;)Ljava/util/Map;
}

public abstract interface class io/sentry/android/core/IDebugImagesLoader {
public abstract fun clearDebugImages ()V
public abstract fun loadDebugImages ()Ljava/util/List;
Expand All @@ -98,6 +105,14 @@ public final class io/sentry/android/core/NdkIntegration : io/sentry/Integration
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/NoOpActivityFramesTracker : io/sentry/android/core/IActivityFramesTracker {
public fun <init> ()V
public fun addActivity (Landroid/app/Activity;)V
public fun setMetrics (Landroid/app/Activity;Lio/sentry/protocol/SentryId;)V
public fun stop ()V
public fun takeMetrics (Lio/sentry/protocol/SentryId;)Ljava/util/Map;
}

public final class io/sentry/android/core/PhoneStateBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
Expand Down Expand Up @@ -136,6 +151,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun isAnrReportInDebug ()Z
public fun isAttachScreenshot ()Z
public fun isCollectAdditionalContext ()Z
public fun isEnableActivityFramesTracking ()Z
public fun isEnableActivityLifecycleBreadcrumbs ()Z
public fun isEnableActivityLifecycleTracingAutoFinish ()Z
public fun isEnableAppComponentBreadcrumbs ()Z
Expand All @@ -150,6 +166,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun setAttachScreenshot (Z)V
public fun setCollectAdditionalContext (Z)V
public fun setDebugImagesLoader (Lio/sentry/android/core/IDebugImagesLoader;)V
public fun setEnableActivityFramesTracking (Z)V
public fun setEnableActivityLifecycleBreadcrumbs (Z)V
public fun setEnableActivityLifecycleTracingAutoFinish (Z)V
public fun setEnableAppComponentBreadcrumbs (Z)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* androidx.core package. It also checks if the FrameMetricsAggregator class is available at
* runtime.
*/
public final class ActivityFramesTracker {
public final class ActivityFramesTracker implements IActivityFramesTracker {

private @Nullable FrameMetricsAggregator frameMetricsAggregator = null;
private boolean androidXAvailable = true;
Expand Down Expand Up @@ -69,6 +69,7 @@ private boolean isFrameMetricsAggregatorAvailable() {
return androidXAvailable && frameMetricsAggregator != null;
}

@Override
@SuppressWarnings("NullAway")
public synchronized void addActivity(final @NotNull Activity activity) {
if (!isFrameMetricsAggregatorAvailable()) {
Expand Down Expand Up @@ -123,6 +124,7 @@ private void snapshotFrameCountsAtStart(final @NotNull Activity activity) {
return new FrameCounts(totalFrames, slowFrames, frozenFrames);
}

@Override
@SuppressWarnings("NullAway")
public synchronized void setMetrics(
final @NotNull Activity activity, final @NotNull SentryId transactionId) {
Expand Down Expand Up @@ -183,6 +185,7 @@ public synchronized void setMetrics(
return new FrameCounts(diffTotalFrames, diffSlowFrames, diffFrozenFrames);
}

@Override
@Nullable
public synchronized Map<String, @NotNull MeasurementValue> takeMetrics(
final @NotNull SentryId transactionId) {
Expand All @@ -196,6 +199,7 @@ public synchronized void setMetrics(
return stringMeasurementValueMap;
}

@Override
@SuppressWarnings("NullAway")
public synchronized void stop() {
if (isFrameMetricsAggregatorAvailable()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ public final class ActivityLifecycleIntegration
private final @NotNull WeakHashMap<Activity, ITransaction> activitiesWithOngoingTransactions =
new WeakHashMap<>();

private final @NotNull ActivityFramesTracker activityFramesTracker;
private final @NotNull IActivityFramesTracker activityFramesTracker;

public ActivityLifecycleIntegration(
final @NotNull Application application,
final @NotNull BuildInfoProvider buildInfoProvider,
final @NotNull ActivityFramesTracker activityFramesTracker) {
final @NotNull IActivityFramesTracker activityFramesTracker) {
this.application = Objects.requireNonNull(application, "Application is required");
Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required");
this.activityFramesTracker =
Expand Down Expand Up @@ -387,6 +387,12 @@ WeakHashMap<Activity, ITransaction> getActivitiesWithOngoingTransactions() {
return activitiesWithOngoingTransactions;
}

@TestOnly
@NotNull
IActivityFramesTracker getActivityFramesTracker() {
return activityFramesTracker;
}

@TestOnly
@Nullable
ISpan getAppStartSpan() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,11 @@ static void init(
initializeCacheDirs(context, options);
options.setEnvelopeDiskCache(new AndroidEnvelopeCache(options));

final ActivityFramesTracker activityFramesTracker =
new ActivityFramesTracker(loadClass, options.getLogger());
final IActivityFramesTracker activityFramesTracker =
options.isEnableActivityFramesTracking()
? new ActivityFramesTracker(loadClass, options.getLogger())
: new NoOpActivityFramesTracker();

installDefaultIntegrations(
context,
options,
Expand All @@ -161,7 +164,7 @@ private static void installDefaultIntegrations(
final @NotNull SentryAndroidOptions options,
final @NotNull BuildInfoProvider buildInfoProvider,
final @NotNull LoadClass loadClass,
final @NotNull ActivityFramesTracker activityFramesTracker,
final @NotNull IActivityFramesTracker activityFramesTracker,
final boolean isFragmentAvailable,
final boolean isTimberAvailable) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.sentry.android.core;

import android.app.Activity;
import io.sentry.protocol.MeasurementValue;
import io.sentry.protocol.SentryId;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface IActivityFramesTracker {
@SuppressWarnings("NullAway")
void addActivity(@NotNull Activity activity);

@SuppressWarnings("NullAway")
void setMetrics(@NotNull Activity activity, @NotNull SentryId transactionId);

@Nullable
Map<String, @NotNull MeasurementValue> takeMetrics(@NotNull SentryId transactionId);

@SuppressWarnings("NullAway")
void stop();
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ final class ManifestMetadataReader {
static final String CLIENT_REPORTS_ENABLE = "io.sentry.send-client-reports";
static final String COLLECT_ADDITIONAL_CONTEXT = "io.sentry.additional-context";

static final String PERFORM_ACTIVITY_FRAMES_TRACKING = "io.sentry.activity-frames-tracking";

/** ManifestMetadataReader ctor */
private ManifestMetadataReader() {}

Expand Down Expand Up @@ -286,6 +288,11 @@ static void applyMetadata(
options.setTracePropagationTargets(tracePropagationTargets);
}

if (metadata.containsKey(PERFORM_ACTIVITY_FRAMES_TRACKING)) {
options.setEnableActivityFramesTracking(
readBool(metadata, logger, PERFORM_ACTIVITY_FRAMES_TRACKING, true));
}

options.setProguardUuid(
readString(metadata, logger, PROGUARD_UUID, options.getProguardUuid()));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.sentry.android.core;

import android.app.Activity;
import io.sentry.protocol.MeasurementValue;
import io.sentry.protocol.SentryId;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class NoOpActivityFramesTracker implements IActivityFramesTracker {
@Override
public void addActivity(@NotNull Activity activity) {}

@Override
public void setMetrics(@NotNull Activity activity, @NotNull SentryId transactionId) {}

@Override
public @Nullable Map<String, @NotNull MeasurementValue> takeMetrics(
@NotNull SentryId transactionId) {
return null;
}

@Override
public void stop() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ final class PerformanceAndroidEventProcessor implements EventProcessor {

private boolean sentStartMeasurement = false;

private final @NotNull ActivityFramesTracker activityFramesTracker;
private final @NotNull IActivityFramesTracker activityFramesTracker;
private final @NotNull SentryAndroidOptions options;

PerformanceAndroidEventProcessor(
final @NotNull SentryAndroidOptions options,
final @NotNull ActivityFramesTracker activityFramesTracker) {
final @NotNull IActivityFramesTracker activityFramesTracker) {
this.options = Objects.requireNonNull(options, "SentryAndroidOptions is required");
this.activityFramesTracker =
Objects.requireNonNull(activityFramesTracker, "ActivityFramesTracker is required");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ public final class SentryAndroidOptions extends SentryOptions {
*/
private final long startupCrashDurationThresholdMillis = 2000; // 2s

private boolean enableActivityFramesTracking = true;

public SentryAndroidOptions() {
setSentryClientName(BuildConfig.SENTRY_ANDROID_SDK_NAME + "/" + BuildConfig.VERSION_NAME);
setSdkVersion(createSdkVersion());
Expand Down Expand Up @@ -357,6 +359,20 @@ public void setCollectAdditionalContext(boolean collectAdditionalContext) {
this.collectAdditionalContext = collectAdditionalContext;
}

public boolean isEnableActivityFramesTracking() {
return enableActivityFramesTracking;
}

/**
* Enable or disable Activity Frames Tracking, which is used to report slow and frozen frames.
*
* @param enableActivityFramesTracking true if activity frames tracking should be enabled, false
* otherwise.
*/
public void setEnableActivityFramesTracking(boolean enableActivityFramesTracking) {
this.enableActivityFramesTracking = enableActivityFramesTracking;
}

/**
* Returns the Startup Crash flush timeout in Millis
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,34 @@ class AndroidOptionsInitializerTest {

assertTrue { fixture.sentryOptions.envelopeDiskCache is AndroidEnvelopeCache }
}

@Test
fun `When Activity Frames Tracking is enabled, the proper class should be initialized`() {
fixture.initSut(hasAppContext = true, configureOptions = {
isEnableActivityFramesTracking = true
})

val activityLifeCycleIntegration = fixture.sentryOptions.integrations
.first { it is ActivityLifecycleIntegration }

assertTrue(
(activityLifeCycleIntegration as ActivityLifecycleIntegration).activityFramesTracker
is ActivityFramesTracker
)
}

@Test
fun `When Activity Frames Tracking is disabled, a noop should be initialized`() {
fixture.initSut(hasAppContext = true, configureOptions = {
isEnableActivityFramesTracking = false
})

val activityLifeCycleIntegration = fixture.sentryOptions.integrations
.first { it is ActivityLifecycleIntegration }

assertTrue(
(activityLifeCycleIntegration as ActivityLifecycleIntegration).activityFramesTracker
is NoOpActivityFramesTracker
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1061,4 +1061,42 @@ class ManifestMetadataReaderTest {
// Assert
assertTrue(fixture.options.isCollectAdditionalContext)
}

@Test
fun `applyMetadata reads activity frames tracker flag and keeps default value if not found`() {
// Arrange
val context = fixture.getContext()

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

// Assert
assertTrue(fixture.options.isEnableActivityFramesTracking)
}

@Test
fun `applyMetadata reads activity frames tracker and sets it to enabled if true`() {
// Arrange
val bundle = bundleOf(ManifestMetadataReader.PERFORM_ACTIVITY_FRAMES_TRACKING to true)
val context = fixture.getContext(metaData = bundle)

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

// Assert
assertTrue(fixture.options.isEnableActivityFramesTracking)
}

@Test
fun `applyMetadata reads activity frames tracker and sets it to disabled if false`() {
// Arrange
val bundle = bundleOf(ManifestMetadataReader.PERFORM_ACTIVITY_FRAMES_TRACKING to false)
val context = fixture.getContext(metaData = bundle)

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

// Assert
assertFalse(fixture.options.isEnableActivityFramesTracking)
}
}

0 comments on commit a3665da

Please sign in to comment.