From a0a094a6359d1c83222f76b104262b1068e66520 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 25 Oct 2022 14:19:00 +0200 Subject: [PATCH] add opt-in to options for screenshot feature --- dart/lib/src/sentry_options.dart | 3 +++ .../integrations/screenshot_integration.dart | 21 +++++++++------- flutter/lib/src/sentry_flutter.dart | 3 +++ .../screenshot_integration_test.dart | 24 +++++++++++++++++-- flutter/test/sentry_flutter_test.dart | 8 ++++++- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/dart/lib/src/sentry_options.dart b/dart/lib/src/sentry_options.dart index 3cad7a2233..736912400e 100644 --- a/dart/lib/src/sentry_options.dart +++ b/dart/lib/src/sentry_options.dart @@ -355,6 +355,9 @@ class SentryOptions { late SentryStackTraceFactory stackTraceFactory = SentryStackTraceFactory(this); + /// Automatically attaches a screenshot when capturing an error or exception. + bool attachScreenshot = false; + @internal late SentryClientAttachmentProcessor clientAttachmentProcessor = SentryClientAttachmentProcessor(); diff --git a/flutter/lib/src/integrations/screenshot_integration.dart b/flutter/lib/src/integrations/screenshot_integration.dart index 3abdb2a069..762d30b007 100644 --- a/flutter/lib/src/integrations/screenshot_integration.dart +++ b/flutter/lib/src/integrations/screenshot_integration.dart @@ -10,15 +10,18 @@ class ScreenshotIntegration implements Integration { @override FutureOr call(Hub hub, SentryFlutterOptions options) { - // ignore: invalid_use_of_internal_member - options.clientAttachmentProcessor = ScreenshotAttachmentProcessor(() { - try { - /// Flutter >= 2.12 throws if SchedulerBinding.instance isn't initialized. - return SchedulerBinding.instance; - } catch (_) {} - return null; - }, options); - _options = options; + if (options.attachScreenshot) { + // ignore: invalid_use_of_internal_member + options.clientAttachmentProcessor = ScreenshotAttachmentProcessor(() { + try { + /// Flutter >= 2.12 throws if SchedulerBinding.instance isn't initialized. + return SchedulerBinding.instance; + } catch (_) {} + return null; + }, options); + _options = options; + } + options.sdk.addIntegration('screenshotIntegration'); } @override diff --git a/flutter/lib/src/sentry_flutter.dart b/flutter/lib/src/sentry_flutter.dart index e5ac9ff5eb..e1e398bb97 100644 --- a/flutter/lib/src/sentry_flutter.dart +++ b/flutter/lib/src/sentry_flutter.dart @@ -140,6 +140,9 @@ mixin SentryFlutter { !platformChecker.isWeb && (platform.isAndroid || platform.isIOS || platform.isMacOS)) { integrations.add(LoadImageListIntegration(channel)); + } + + if (platform.isAndroid || platform.isIOS || platform.isMacOS) { integrations.add(ScreenshotIntegration()); } diff --git a/flutter/test/integrations/screenshot_integration_test.dart b/flutter/test/integrations/screenshot_integration_test.dart index 0ceed062b8..38a58e1cca 100644 --- a/flutter/test/integrations/screenshot_integration_test.dart +++ b/flutter/test/integrations/screenshot_integration_test.dart @@ -15,7 +15,7 @@ void main() { }); test('screenshotIntegration creates screenshot processor', () async { - final integration = ScreenshotIntegration(); + final integration = fixture.getSut(); await integration(fixture.hub, fixture.options); @@ -26,8 +26,23 @@ void main() { true); }); + test( + 'screenshotIntegration does not creates screenshot processor if opt out in options', + () async { + final integration = fixture.getSut(); + fixture.options.attachScreenshot = false; + + await integration(fixture.hub, fixture.options); + + expect( + // ignore: invalid_use_of_internal_member + fixture.options.clientAttachmentProcessor + is ScreenshotAttachmentProcessor, + false); + }); + test('screenshotIntegration close resets processor', () async { - final integration = ScreenshotIntegration(); + final integration = fixture.getSut(); await integration(fixture.hub, fixture.options); await integration.close(); @@ -43,4 +58,9 @@ void main() { class Fixture { final hub = MockHub(); final options = SentryFlutterOptions(); + + ScreenshotIntegration getSut() { + options.attachScreenshot = true; + return ScreenshotIntegration(); + } } diff --git a/flutter/test/sentry_flutter_test.dart b/flutter/test/sentry_flutter_test.dart index f57d8527be..0913b0741f 100644 --- a/flutter/test/sentry_flutter_test.dart +++ b/flutter/test/sentry_flutter_test.dart @@ -2,6 +2,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/integrations/integrations.dart'; +import 'package:sentry_flutter/src/integrations/screenshot_integration.dart'; import 'package:sentry_flutter/src/version.dart'; import 'mocks.dart'; import 'mocks.mocks.dart'; @@ -20,12 +21,14 @@ final platformAgnosticIntegrations = [ // These should only be added to Android final androidIntegrations = [ LoadImageListIntegration, + ScreenshotIntegration, ]; // These should be added to iOS and macOS final iOsAndMacOsIntegrations = [ LoadImageListIntegration, LoadContextsIntegration, + ScreenshotIntegration, ]; // These should be added to every platform which has a native integration. @@ -48,6 +51,7 @@ void main() { await SentryFlutter.init( (options) async { options.dsn = fakeDsn; + options.attachScreenshot = true; integrations = options.integrations; transport = options.transport; }, @@ -88,6 +92,7 @@ void main() { await SentryFlutter.init( (options) async { options.dsn = fakeDsn; + options.attachScreenshot = true; integrations = options.integrations; transport = options.transport; }, @@ -126,6 +131,7 @@ void main() { await SentryFlutter.init( (options) async { options.dsn = fakeDsn; + options.attachScreenshot = true; integrations = options.integrations; transport = options.transport; }, @@ -364,7 +370,7 @@ void main() { List integrations = []; Transport transport = MockTransport(); - // Tests that Android integrations aren't added on an Android browswer + // Tests that Android integrations aren't added on an Android browser await SentryFlutter.init( (options) async { options.dsn = fakeDsn;