Skip to content

Commit bf94edf

Browse files
authored
Merge 7069634 into 7e57220
2 parents 7e57220 + 7069634 commit bf94edf

File tree

20 files changed

+958
-128
lines changed

20 files changed

+958
-128
lines changed

CHANGELOG.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@
66

77
- Add support for `feedback` envelope header item type ([#3687](https://github.com/getsentry/sentry-java/pull/3687))
88
- Add breadcrumb.origin field ([#3727](https://github.com/getsentry/sentry-java/pull/3727))
9+
- Session Replay: Add options to selectively redact/ignore views from being captured. The following options are available: ([#3689](https://github.com/getsentry/sentry-java/pull/3689))
10+
- `android:tag="sentry-redact|sentry-ignore"` in XML or `view.setTag("sentry-redact|sentry-ignore")` in code tags
11+
- if you already have a tag set for a view, you can set a tag by id: `<tag android:id="@id/sentry_privacy" android:value="redact|ignore"/>` in XML or `view.setTag(io.sentry.android.replay.R.id.sentry_privacy, "redact|ignore")` in code
12+
- `view.sentryReplayRedact()` or `view.sentryReplayIgnore()` extension functions
13+
- redact/ignore `View`s of a certain type by adding fully-qualified classname to one of the lists `options.experimental.sessionReplay.addRedactViewClass()` or `options.experimental.sessionReplay.addIgnoreViewClass()`. Note, that all of the view subclasses/subtypes will be redacted/ignored as well
14+
- For example, (this is already a default behavior) to redact all `TextView`s and their subclasses (`RadioButton`, `EditText`, etc.): `options.experimental.sessionReplay.addRedactViewClass("android.widget.TextView")`
15+
- If you're using code obfuscation, adjust your proguard-rules accordingly, so your custom view class name is not minified
16+
- Session Replay: Support Jetpack Compose masking ([#3739](https://github.com/getsentry/sentry-java/pull/3739))
17+
- To selectively mask/unmask @Composables, use `Modifier.sentryReplayRedact()` and `Modifier.sentryReplayIgnore()` modifiers
918

1019
### Fixes
1120

1221
- Avoid stopping appStartProfiler after application creation ([#3630](https://github.com/getsentry/sentry-java/pull/3630))
1322
- Session Replay: Correctly detect dominant color for `TextView`s with Spans ([#3682](https://github.com/getsentry/sentry-java/pull/3682))
14-
- Session Replay: Add options to selectively redact/ignore views from being captured. The following options are available: ([#3689](https://github.com/getsentry/sentry-java/pull/3689))
15-
- `android:tag="sentry-redact|sentry-ignore"` in XML or `view.setTag("sentry-redact|sentry-ignore")` in code tags
16-
- if you already have a tag set for a view, you can set a tag by id: `<tag android:id="@id/sentry_privacy" android:value="redact|ignore"/>` in XML or `view.setTag(io.sentry.android.replay.R.id.sentry_privacy, "redact|ignore")` in code
17-
- `view.sentryReplayRedact()` or `view.sentryReplayIgnore()` extension functions
18-
- redact/ignore `View`s of a certain type by adding fully-qualified classname to one of the lists `options.experimental.sessionReplay.addRedactViewClass()` or `options.experimental.sessionReplay.addIgnoreViewClass()`. Note, that all of the view subclasses/subtypes will be redacted/ignored as well
19-
- For example, (this is already a default behavior) to redact all `TextView`s and their subclasses (`RadioButton`, `EditText`, etc.): `options.experimental.sessionReplay.addRedactViewClass("android.widget.TextView")`
20-
- If you're using code obfuscation, adjust your proguard-rules accordingly, so your custom view class name is not minified
2123
- Fix ensure Application Context is used even when SDK is initialized via Activity Context ([#3669](https://github.com/getsentry/sentry-java/pull/3669))
2224

2325
*Breaking changes*:

buildSrc/src/main/java/Config.kt

+3
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,11 @@ object Config {
147147
val composeActivity = "androidx.activity:activity-compose:1.4.0"
148148
val composeFoundation = "androidx.compose.foundation:foundation:$composeVersion"
149149
val composeUi = "androidx.compose.ui:ui:$composeVersion"
150+
151+
val composeUiReplay = "androidx.compose.ui:ui:1.5.0" // Note: don't change without testing forwards compatibility
150152
val composeFoundationLayout = "androidx.compose.foundation:foundation-layout:$composeVersion"
151153
val composeMaterial = "androidx.compose.material3:material3:1.0.0-alpha13"
154+
val composeCoil = "io.coil-kt:coil-compose:2.6.0"
152155

153156
val apolloKotlin = "com.apollographql.apollo3:apollo-runtime:3.8.2"
154157

sentry-android-replay/api/sentry-android-replay.api

+51-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ public final class io/sentry/android/replay/BuildConfig {
77
}
88

99
public class io/sentry/android/replay/DefaultReplayBreadcrumbConverter : io/sentry/ReplayBreadcrumbConverter {
10+
public static final field $stable I
1011
public fun <init> ()V
1112
public fun convert (Lio/sentry/Breadcrumb;)Lio/sentry/rrweb/RRWebEvent;
1213
}
1314

1415
public final class io/sentry/android/replay/GeneratedVideo {
16+
public static final field $stable I
1517
public fun <init> (Ljava/io/File;IJ)V
1618
public final fun component1 ()Ljava/io/File;
1719
public final fun component2 ()I
@@ -26,6 +28,11 @@ public final class io/sentry/android/replay/GeneratedVideo {
2628
public fun toString ()Ljava/lang/String;
2729
}
2830

31+
public final class io/sentry/android/replay/ModifierExtensionsKt {
32+
public static final fun sentryReplayIgnore (Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
33+
public static final fun sentryReplayRedact (Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
34+
}
35+
2936
public abstract interface class io/sentry/android/replay/Recorder : java/io/Closeable {
3037
public abstract fun pause ()V
3138
public abstract fun resume ()V
@@ -34,6 +41,7 @@ public abstract interface class io/sentry/android/replay/Recorder : java/io/Clos
3441
}
3542

3643
public final class io/sentry/android/replay/ReplayCache : java/io/Closeable {
44+
public static final field $stable I
3745
public static final field Companion Lio/sentry/android/replay/ReplayCache$Companion;
3846
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/protocol/SentryId;Lio/sentry/android/replay/ScreenshotRecorderConfig;)V
3947
public final fun addFrame (Ljava/io/File;JLjava/lang/String;)V
@@ -50,6 +58,7 @@ public final class io/sentry/android/replay/ReplayCache$Companion {
5058
}
5159

5260
public final class io/sentry/android/replay/ReplayIntegration : android/content/ComponentCallbacks, io/sentry/Integration, io/sentry/ReplayController, io/sentry/android/replay/ScreenshotRecorderCallback, io/sentry/android/replay/gestures/TouchRecorderCallback, java/io/Closeable {
61+
public static final field $stable I
5362
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;)V
5463
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
5564
public synthetic fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@@ -78,6 +87,7 @@ public abstract interface class io/sentry/android/replay/ScreenshotRecorderCallb
7887
}
7988

8089
public final class io/sentry/android/replay/ScreenshotRecorderConfig {
90+
public static final field $stable I
8191
public static final field Companion Lio/sentry/android/replay/ScreenshotRecorderConfig$Companion;
8292
public fun <init> (IIFFII)V
8393
public final fun component1 ()I
@@ -103,6 +113,12 @@ public final class io/sentry/android/replay/ScreenshotRecorderConfig$Companion {
103113
public final fun from (Landroid/content/Context;Lio/sentry/SentryReplayOptions;)Lio/sentry/android/replay/ScreenshotRecorderConfig;
104114
}
105115

116+
public final class io/sentry/android/replay/SentryReplayModifiers {
117+
public static final field $stable I
118+
public static final field INSTANCE Lio/sentry/android/replay/SentryReplayModifiers;
119+
public final fun getSentryPrivacy ()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
120+
}
121+
106122
public final class io/sentry/android/replay/SessionReplayOptionsKt {
107123
public static final fun getRedactAllImages (Lio/sentry/SentryReplayOptions;)Z
108124
public static final fun getRedactAllText (Lio/sentry/SentryReplayOptions;)Z
@@ -116,12 +132,14 @@ public final class io/sentry/android/replay/ViewExtensionsKt {
116132
}
117133

118134
public final class io/sentry/android/replay/gestures/GestureRecorder : io/sentry/android/replay/OnRootViewsChangedListener {
135+
public static final field $stable I
119136
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/android/replay/gestures/TouchRecorderCallback;)V
120137
public fun onRootViewsChanged (Landroid/view/View;Z)V
121138
public final fun stop ()V
122139
}
123140

124141
public final class io/sentry/android/replay/gestures/ReplayGestureConverter {
142+
public static final field $stable I
125143
public fun <init> (Lio/sentry/transport/ICurrentDateProvider;)V
126144
public final fun convert (Landroid/view/MotionEvent;Lio/sentry/android/replay/ScreenshotRecorderConfig;)Ljava/util/List;
127145
}
@@ -130,6 +148,19 @@ public abstract interface class io/sentry/android/replay/gestures/TouchRecorderC
130148
public abstract fun onTouchEvent (Landroid/view/MotionEvent;)V
131149
}
132150

151+
public final class io/sentry/android/replay/util/AndroidTextLayout : io/sentry/android/replay/util/TextLayout {
152+
public static final field $stable I
153+
public fun <init> (Landroid/text/Layout;)V
154+
public fun getDominantTextColor ()Ljava/lang/Integer;
155+
public fun getEllipsisCount (I)I
156+
public fun getLineBottom (I)I
157+
public fun getLineCount ()I
158+
public fun getLineStart (I)I
159+
public fun getLineTop (I)I
160+
public fun getLineVisibleEnd (I)I
161+
public fun getPrimaryHorizontal (II)F
162+
}
163+
133164
public class io/sentry/android/replay/util/FixedWindowCallback : android/view/Window$Callback {
134165
public final field delegate Landroid/view/Window$Callback;
135166
public fun <init> (Landroid/view/Window$Callback;)V
@@ -160,6 +191,17 @@ public class io/sentry/android/replay/util/FixedWindowCallback : android/view/Wi
160191
public fun onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
161192
}
162193

194+
public abstract interface class io/sentry/android/replay/util/TextLayout {
195+
public abstract fun getDominantTextColor ()Ljava/lang/Integer;
196+
public abstract fun getEllipsisCount (I)I
197+
public abstract fun getLineBottom (I)I
198+
public abstract fun getLineCount ()I
199+
public abstract fun getLineStart (I)I
200+
public abstract fun getLineTop (I)I
201+
public abstract fun getLineVisibleEnd (I)I
202+
public abstract fun getPrimaryHorizontal (II)F
203+
}
204+
163205
public abstract interface class io/sentry/android/replay/video/SimpleFrameMuxer {
164206
public abstract fun getVideoTime ()J
165207
public abstract fun isStarted ()Z
@@ -169,6 +211,7 @@ public abstract interface class io/sentry/android/replay/video/SimpleFrameMuxer
169211
}
170212

171213
public final class io/sentry/android/replay/video/SimpleMp4FrameMuxer : io/sentry/android/replay/video/SimpleFrameMuxer {
214+
public static final field $stable I
172215
public fun <init> (Ljava/lang/String;F)V
173216
public fun getVideoTime ()J
174217
public fun isStarted ()Z
@@ -178,6 +221,7 @@ public final class io/sentry/android/replay/video/SimpleMp4FrameMuxer : io/sentr
178221
}
179222

180223
public abstract class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode {
224+
public static final field $stable I
181225
public static final field Companion Lio/sentry/android/replay/viewhierarchy/ViewHierarchyNode$Companion;
182226
public synthetic fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
183227
public synthetic fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
@@ -195,6 +239,7 @@ public abstract class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode {
195239
public final fun isObscured (Lio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;)Z
196240
public final fun isVisible ()Z
197241
public final fun setChildren (Ljava/util/List;)V
242+
public final fun setImportantForCaptureToAncestors (Z)V
198243
public final fun setImportantForContentCapture (Z)V
199244
public final fun traverse (Lkotlin/jvm/functions/Function1;)V
200245
}
@@ -204,20 +249,23 @@ public final class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode$Comp
204249
}
205250

206251
public final class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode$GenericViewHierarchyNode : io/sentry/android/replay/viewhierarchy/ViewHierarchyNode {
252+
public static final field $stable I
207253
public fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;)V
208254
public synthetic fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
209255
}
210256

211257
public final class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode$ImageViewHierarchyNode : io/sentry/android/replay/viewhierarchy/ViewHierarchyNode {
258+
public static final field $stable I
212259
public fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;)V
213260
public synthetic fun <init> (FFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
214261
}
215262

216263
public final class io/sentry/android/replay/viewhierarchy/ViewHierarchyNode$TextViewHierarchyNode : io/sentry/android/replay/viewhierarchy/ViewHierarchyNode {
217-
public fun <init> (Landroid/text/Layout;Ljava/lang/Integer;IIFFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;)V
218-
public synthetic fun <init> (Landroid/text/Layout;Ljava/lang/Integer;IIFFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
264+
public static final field $stable I
265+
public fun <init> (Lio/sentry/android/replay/util/TextLayout;Ljava/lang/Integer;IIFFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;)V
266+
public synthetic fun <init> (Lio/sentry/android/replay/util/TextLayout;Ljava/lang/Integer;IIFFIIFILio/sentry/android/replay/viewhierarchy/ViewHierarchyNode;ZZZLandroid/graphics/Rect;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
219267
public final fun getDominantColor ()Ljava/lang/Integer;
220-
public final fun getLayout ()Landroid/text/Layout;
268+
public final fun getLayout ()Lio/sentry/android/replay/util/TextLayout;
221269
public final fun getPaddingLeft ()I
222270
public final fun getPaddingTop ()I
223271
}

sentry-android-replay/build.gradle.kts

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import io.gitlab.arturbosch.detekt.Detekt
22
import org.jetbrains.kotlin.config.KotlinCompilerVersion
3+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
34

45
plugins {
56
id("com.android.library")
@@ -25,9 +26,19 @@ android {
2526
buildConfigField("String", "VERSION_NAME", "\"${project.version}\"")
2627
}
2728

29+
buildFeatures {
30+
compose = true
31+
}
32+
33+
composeOptions {
34+
kotlinCompilerExtensionVersion = Config.androidComposeCompilerVersion
35+
}
36+
2837
buildTypes {
2938
getByName("debug")
30-
getByName("release")
39+
getByName("release") {
40+
consumerProguardFiles("proguard-rules.pro")
41+
}
3142
}
3243

3344
kotlinOptions {
@@ -65,6 +76,7 @@ kotlin {
6576
dependencies {
6677
api(projects.sentry)
6778

79+
compileOnly(Config.Libs.composeUiReplay)
6880
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
6981

7082
// tests
@@ -77,9 +89,19 @@ dependencies {
7789
testImplementation(Config.TestLibs.mockitoKotlin)
7890
testImplementation(Config.TestLibs.mockitoInline)
7991
testImplementation(Config.TestLibs.awaitility)
92+
testImplementation(Config.Libs.composeActivity)
93+
testImplementation(Config.Libs.composeUi)
94+
testImplementation(Config.Libs.composeCoil)
95+
testImplementation(Config.Libs.composeFoundation)
96+
testImplementation(Config.Libs.composeFoundationLayout)
97+
testImplementation(Config.Libs.composeMaterial)
8098
}
8199

82100
tasks.withType<Detekt> {
83101
// Target version of the generated JVM bytecode. It is used for type resolution.
84102
jvmTarget = JavaVersion.VERSION_1_8.toString()
85103
}
104+
105+
tasks.withType<KotlinCompilationTask<*>>().configureEach {
106+
compilerOptions.freeCompilerArgs.add("-opt-in=androidx.compose.ui.ExperimentalComposeUiApi")
107+
}
+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
# Uncomment this to preserve the line number information for
22
# debugging stack traces.
33
-keepattributes SourceFile,LineNumberTable
4+
5+
# Rules to detect Images/Icons and redact them
6+
-dontwarn androidx.compose.ui.graphics.painter.Painter
7+
-keepnames class * extends androidx.compose.ui.graphics.painter.Painter
8+
-keepclasseswithmembernames class * {
9+
androidx.compose.ui.graphics.painter.Painter painter;
10+
}
11+
# Rules to detect Text colors and if they have Modifier.fillMaxWidth to later redact them
12+
-dontwarn androidx.compose.ui.graphics.ColorProducer
13+
-dontwarn androidx.compose.foundation.layout.FillElement
14+
-keepnames class androidx.compose.foundation.layout.FillElement
15+
-keepclasseswithmembernames class * {
16+
androidx.compose.ui.graphics.ColorProducer color;
17+
}
18+
# Rules to detect a compose view to parse its hierarchy
19+
-dontwarn androidx.compose.ui.platform.AndroidComposeView
20+
-keepnames class androidx.compose.ui.platform.AndroidComposeView
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.sentry.android.replay
2+
3+
import androidx.compose.ui.Modifier
4+
import androidx.compose.ui.semantics.SemanticsPropertyKey
5+
import androidx.compose.ui.semantics.semantics
6+
import io.sentry.android.replay.SentryReplayModifiers.SentryPrivacy
7+
8+
public object SentryReplayModifiers {
9+
val SentryPrivacy = SemanticsPropertyKey<String>(
10+
name = "SentryPrivacy",
11+
mergePolicy = { parentValue, _ -> parentValue }
12+
)
13+
}
14+
15+
public fun Modifier.sentryReplayRedact(): Modifier {
16+
return semantics(
17+
properties = {
18+
this[SentryPrivacy] = "redact"
19+
}
20+
)
21+
}
22+
23+
public fun Modifier.sentryReplayIgnore(): Modifier {
24+
return semantics(
25+
properties = {
26+
this[SentryPrivacy] = "ignore"
27+
}
28+
)
29+
}

0 commit comments

Comments
 (0)