diff --git a/sentry-android-replay/src/main/java/io/sentry/android/replay/viewhierarchy/ViewHierarchyNode.kt b/sentry-android-replay/src/main/java/io/sentry/android/replay/viewhierarchy/ViewHierarchyNode.kt index 60014e8f64..1a94b295f7 100644 --- a/sentry-android-replay/src/main/java/io/sentry/android/replay/viewhierarchy/ViewHierarchyNode.kt +++ b/sentry-android-replay/src/main/java/io/sentry/android/replay/viewhierarchy/ViewHierarchyNode.kt @@ -232,6 +232,10 @@ sealed class ViewHierarchyNode( } } + private fun shouldRedact(view: View, options: SentryOptions): Boolean { + return options.experimental.sessionReplay.redactClasses.contains(view.javaClass.canonicalName) + } + fun fromView(view: View, parent: ViewHierarchyNode?, distance: Int, options: SentryOptions): ViewHierarchyNode { val (isVisible, visibleRect) = view.isVisibleToUser() when { @@ -282,7 +286,7 @@ sealed class ViewHierarchyNode( (parent?.elevation ?: 0f) + view.elevation, distance = distance, parent = parent, - shouldRedact = false, + shouldRedact = isVisible && shouldRedact(view, options), isImportantForContentCapture = false, /* will be set by children */ isVisible = isVisible, visibleRect = visibleRect diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index f662b29efb..af9ffe9fc4 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -2699,12 +2699,14 @@ public final class io/sentry/SentryReplayEvent$ReplayType$Deserializer : io/sent public final class io/sentry/SentryReplayOptions { public fun ()V public fun (Ljava/lang/Double;Ljava/lang/Double;)V + public fun addClassToRedact (Ljava/lang/String;)V public fun getErrorReplayDuration ()J public fun getErrorSampleRate ()Ljava/lang/Double; public fun getFrameRate ()I public fun getQuality ()Lio/sentry/SentryReplayOptions$SentryReplayQuality; public fun getRedactAllImages ()Z public fun getRedactAllText ()Z + public fun getRedactClasses ()Ljava/util/Set; public fun getSessionDuration ()J public fun getSessionSampleRate ()Ljava/lang/Double; public fun getSessionSegmentDuration ()J diff --git a/sentry/src/main/java/io/sentry/SentryReplayOptions.java b/sentry/src/main/java/io/sentry/SentryReplayOptions.java index 54cabeaef6..db230f2a30 100644 --- a/sentry/src/main/java/io/sentry/SentryReplayOptions.java +++ b/sentry/src/main/java/io/sentry/SentryReplayOptions.java @@ -1,6 +1,8 @@ package io.sentry; import io.sentry.util.SampleRateUtils; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,6 +66,14 @@ public enum SentryReplayQuality { */ private boolean redactAllImages = true; + /** + * Redact all views with the specified class names. The class name is the fully qualified class + * name of the view, e.g. android.widget.TextView. + * + *

Default is empty. + */ + private Set redactClasses = new CopyOnWriteArraySet<>(); + /** * Defines the quality of the session replay. The higher the quality, the more accurate the replay * will be, but also more data to transfer and more CPU load, defaults to MEDIUM. @@ -147,6 +157,14 @@ public void setRedactAllImages(final boolean redactAllImages) { this.redactAllImages = redactAllImages; } + public Set getRedactClasses() { + return this.redactClasses; + } + + public void addClassToRedact(final String className) { + this.redactClasses.add(className); + } + @ApiStatus.Internal public @NotNull SentryReplayQuality getQuality() { return quality;