Skip to content

Commit

Permalink
move replay and privacy from experimaental to options
Browse files Browse the repository at this point in the history
  • Loading branch information
denrase committed Feb 25, 2025
1 parent bb29ef9 commit 64612d7
Show file tree
Hide file tree
Showing 18 changed files with 1,388 additions and 1,627 deletions.
8 changes: 2 additions & 6 deletions flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,8 @@ Future<void> setupSentry(
options.maxRequestBodySize = MaxRequestBodySize.always;
options.navigatorKey = navigatorKey;

options.experimental.replay.sessionSampleRate = 1.0;
options.experimental.replay.onErrorSampleRate = 1.0;

// This has a side-effect of creating the default privacy configuration,
// thus enabling Screenshot masking. No need to actually change it.
options.experimental.privacy;
options.replay.sessionSampleRate = 1.0;
options.replay.onErrorSampleRate = 1.0;

_isIntegrationTest = isIntegrationTest;
if (_isIntegrationTest) {
Expand Down
3 changes: 1 addition & 2 deletions flutter/lib/src/native/cocoa/cocoa_replay_recorder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class CocoaReplayRecorder {
CocoaReplayRecorder(this._options)
: _recorder = ReplayScreenshotRecorder(
ScreenshotRecorderConfig(
pixelRatio:
_options.experimental.replay.quality.resolutionScalingFactor,
pixelRatio: _options.replay.quality.resolutionScalingFactor,
),
_options,
);
Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/native/cocoa/sentry_native_cocoa.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class SentryNativeCocoa extends SentryNativeChannel {
Future<void> init(Hub hub) async {
// We only need these when replay is enabled (session or error capture)
// so let's set it up conditionally. This allows Dart to trim the code.
if (options.experimental.replay.isEnabled) {
if (options.replay.isEnabled) {
channel.setMethodCallHandler((call) async {
switch (call.method) {
case 'captureReplayScreenshot':
Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/native/java/sentry_native_java.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SentryNativeJava extends SentryNativeChannel {
Future<void> init(Hub hub) async {
// We only need these when replay is enabled (session or error capture)
// so let's set it up conditionally. This allows Dart to trim the code.
if (options.experimental.replay.isEnabled) {
if (options.replay.isEnabled) {
channel.setMethodCallHandler((call) async {
switch (call.method) {
case 'ReplayRecorder.start':
Expand Down
16 changes: 8 additions & 8 deletions flutter/lib/src/native/sentry_native_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ class SentryNativeChannel
options.appHangTimeoutInterval.inMilliseconds,
if (options.proxy != null) 'proxy': options.proxy?.toJson(),
'replay': <String, dynamic>{
'quality': options.experimental.replay.quality.name,
'sessionSampleRate': options.experimental.replay.sessionSampleRate,
'onErrorSampleRate': options.experimental.replay.onErrorSampleRate,
'quality': options.replay.quality.name,
'sessionSampleRate': options.replay.sessionSampleRate,
'onErrorSampleRate': options.replay.onErrorSampleRate,
'tags': <String, dynamic>{
'maskAllText': options.experimental.privacy.maskAllText,
'maskAllImages': options.experimental.privacy.maskAllImages,
'maskAssetImages': options.experimental.privacy.maskAssetImages,
if (options.experimental.privacy.userMaskingRules.isNotEmpty)
'maskingRules': options.experimental.privacy.userMaskingRules
'maskAllText': options.privacy.maskAllText,
'maskAllImages': options.privacy.maskAllImages,
'maskAssetImages': options.privacy.maskAssetImages,
if (options.privacy.userMaskingRules.isNotEmpty)
'maskingRules': options.privacy.userMaskingRules
.map((rule) => '${rule.name}: ${rule.description}')
.toList(growable: false),
},
Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/replay/integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ReplayIntegration extends Integration<SentryFlutterOptions> {

@override
FutureOr<void> call(Hub hub, SentryFlutterOptions options) {
final replayOptions = options.experimental.replay;
final replayOptions = options.replay;
if (_native.supportsReplay && replayOptions.isEnabled) {
options.sdk.addIntegration(replayIntegrationName);

Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/replay/replay_recorder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var _instanceCounter = 0;
class ReplayScreenshotRecorder extends ScreenshotRecorder {
ReplayScreenshotRecorder(super.config, super.options)
: super(
privacyOptions: options.experimental.privacy,
privacyOptions: options.privacy,
logName: 'ReplayRecorder #${++_instanceCounter}');

@override
Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/screenshot/recorder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ScreenshotRecorder {
SentryPrivacyOptions? privacyOptions,
this.logName = 'ScreenshotRecorder',
}) {
privacyOptions ??= options.experimental.privacy;
privacyOptions ??= options.privacy;

final maskingConfig =
privacyOptions.buildMaskingConfig(_log, options.platformChecker);
Expand Down
22 changes: 7 additions & 15 deletions flutter/lib/src/sentry_flutter_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ class SentryFlutterOptions extends SentryOptions {
/// you must use `SentryWidgetsFlutterBinding.ensureInitialized()` instead.
bool enableFramesTracking = true;

/// Replay recording configuration.
final replay = SentryReplayOptions();

/// Privacy configuration for masking sensitive data in screenshots and Session Replay.
/// Screen content masking is enabled by default.
final privacy = SentryPrivacyOptions();

/// By using this, you are disabling native [Breadcrumb] tracking and instead
/// you are just tracking [Breadcrumb]s which result from events available
/// in the current Flutter environment.
Expand Down Expand Up @@ -368,21 +375,6 @@ class SentryFlutterOptions extends SentryOptions {
@override
// ignore: invalid_use_of_internal_member
set automatedTestMode(bool value) => super.automatedTestMode = value;

/// Configuration of experimental features that may change or be removed
/// without prior notice. Additionally, these features may not be ready for
/// production use yet.
@meta.experimental
final experimental = _SentryFlutterExperimentalOptions();
}

class _SentryFlutterExperimentalOptions {
/// Replay recording configuration.
final replay = SentryReplayOptions();

/// Privacy configuration for masking sensitive data in screenshots and Session Replay.
/// Screen content masking is enabled by default.
final privacy = SentryPrivacyOptions();
}

/// A callback which can be used to suppress capturing of screenshots.
Expand Down
7 changes: 2 additions & 5 deletions flutter/lib/src/sentry_privacy_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@ class SentryPrivacyOptions {
/// Mask all text content. Draws a rectangle of text bounds with text color
/// on top. Currently, only [Text] and [EditableText] Widgets are masked.
/// Default is enabled.
@experimental
var maskAllText = true;

/// Mask content of all images. Draws a rectangle of image bounds with image's
/// dominant color on top. Currently, only [Image] widgets are masked.
/// Default is enabled (except for asset images, see [maskAssetImages]).
@experimental
var maskAllImages = true;

/// Redact asset images coming from the root asset bundle.
@experimental
var maskAssetImages = false;

final _userMaskingRules = <SentryMaskingRule>[];
Expand Down Expand Up @@ -82,8 +79,8 @@ class SentryPrivacyOptions {

// Note: the following line just makes sure if the option is renamed,
// someone will notice that there is a string that needs updating too.
SentryFlutterOptions().experimental.privacy;
final optionsName = 'options.experimental.privacy';
SentryFlutterOptions().privacy;
final optionsName = 'options.privacy';

rules.add(SentryMaskingCustomRule<Widget>(
callback: (Element element, Widget widget) {
Expand Down
3 changes: 1 addition & 2 deletions flutter/lib/src/sentry_replay_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import 'package:meta/meta.dart';

import 'replay/replay_quality.dart';

/// Configuration of the experimental replay feature.
@experimental
/// Configuration of the replay feature.
class SentryReplayOptions {
double? _sessionSampleRate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void main() {

testWidgets('adds screenshot attachment with masking enabled dart:io',
(tester) async {
fixture.options.experimental.privacy.maskAllText = true;
fixture.options.privacy.maskAllText = true;
await _addScreenshotAttachment(tester, null, added: true, isWeb: false);
});

Expand Down
8 changes: 4 additions & 4 deletions flutter/test/integrations/init_native_sdk_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ void main() {
user: 'admin',
pass: '0000',
)
..experimental.replay.quality = SentryReplayQuality.high
..experimental.replay.sessionSampleRate = 0.1
..experimental.replay.onErrorSampleRate = 0.2
..experimental.privacy.mask<Image>()
..replay.quality = SentryReplayQuality.high
..replay.sessionSampleRate = 0.1
..replay.onErrorSampleRate = 0.2
..privacy.mask<Image>()
..spotlight =
Spotlight(enabled: true, url: 'http://localhost:8969/stream');

Expand Down
Loading

0 comments on commit 64612d7

Please sign in to comment.