Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move native SDK init and close to SentryNativeBinding #2030

Merged
merged 6 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 17 additions & 54 deletions flutter/lib/src/integrations/native_sdk_integration.dart
Original file line number Diff line number Diff line change
@@ -1,61 +1,26 @@
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:sentry/sentry.dart';
import '../native/sentry_native.dart';
import '../sentry_flutter_options.dart';

/// Enables Sentry's native SDKs (Android and iOS) with options.
class NativeSdkIntegration implements Integration<SentryFlutterOptions> {
NativeSdkIntegration(this._channel);
NativeSdkIntegration(this._native);

final MethodChannel _channel;
SentryFlutterOptions? _options;
final SentryNative _native;

@override
Future<void> call(Hub hub, SentryFlutterOptions options) async {
_options = options;

if (!options.autoInitializeNativeSdk) {
return;
}
try {
await _channel.invokeMethod('initNativeSdk', <String, dynamic>{
'dsn': options.dsn,
'debug': options.debug,
'environment': options.environment,
'release': options.release,
'enableAutoSessionTracking': options.enableAutoSessionTracking,
'enableNativeCrashHandling': options.enableNativeCrashHandling,
'attachStacktrace': options.attachStacktrace,
'attachThreads': options.attachThreads,
'autoSessionTrackingIntervalMillis':
options.autoSessionTrackingInterval.inMilliseconds,
'dist': options.dist,
'integrations': options.sdk.integrations,
'packages':
options.sdk.packages.map((e) => e.toJson()).toList(growable: false),
'diagnosticLevel': options.diagnosticLevel.name,
'maxBreadcrumbs': options.maxBreadcrumbs,
'anrEnabled': options.anrEnabled,
'anrTimeoutIntervalMillis': options.anrTimeoutInterval.inMilliseconds,
'enableAutoNativeBreadcrumbs': options.enableAutoNativeBreadcrumbs,
'maxCacheItems': options.maxCacheItems,
'sendDefaultPii': options.sendDefaultPii,
'enableWatchdogTerminationTracking':
options.enableWatchdogTerminationTracking,
'enableNdkScopeSync': options.enableNdkScopeSync,
'enableAutoPerformanceTracing': options.enableAutoPerformanceTracing,
'sendClientReports': options.sendClientReports,
'proguardUuid': options.proguardUuid,
'maxAttachmentSize': options.maxAttachmentSize,
'recordHttpBreadcrumbs': options.recordHttpBreadcrumbs,
'captureFailedRequests': options.captureFailedRequests,
'enableAppHangTracking': options.enableAppHangTracking,
'connectionTimeoutMillis': options.connectionTimeout.inMilliseconds,
'readTimeoutMillis': options.readTimeout.inMilliseconds,
'appHangTimeoutIntervalMillis':
options.appHangTimeoutInterval.inMilliseconds,
});

try {
await _native.init(options);
options.sdk.addIntegration('nativeSdkIntegration');
} catch (exception, stackTrace) {
options.logger(
Expand All @@ -69,19 +34,17 @@ class NativeSdkIntegration implements Integration<SentryFlutterOptions> {

@override
Future<void> close() async {
final options = _options;
if (options != null && !options.autoInitializeNativeSdk) {
return;
}
try {
await _channel.invokeMethod('closeNativeSdk');
} catch (exception, stackTrace) {
_options?.logger(
SentryLevel.fatal,
'nativeSdkIntegration failed to be closed',
exception: exception,
stackTrace: stackTrace,
);
if (_options?.autoInitializeNativeSdk == true) {
try {
await _native.close();
} catch (exception, stackTrace) {
_options?.logger(
SentryLevel.fatal,
'nativeSdkIntegration failed to be closed',
exception: exception,
stackTrace: stackTrace,
);
}
}
}
}
3 changes: 3 additions & 0 deletions flutter/lib/src/native/factory_real.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import 'package:flutter/services.dart';

import '../../sentry_flutter.dart';
import 'cocoa/sentry_native_cocoa.dart';
import 'java/sentry_native_java.dart';
import 'sentry_native_binding.dart';
import 'sentry_native_channel.dart';

SentryNativeBinding createBinding(PlatformChecker pc, MethodChannel channel) {
if (pc.platform.isIOS || pc.platform.isMacOS) {
return SentryNativeCocoa(channel);
} else if (pc.platform.isAndroid) {
return SentryNativeJava(channel);
} else {
return SentryNativeChannel(channel);
}
Expand Down
2 changes: 1 addition & 1 deletion flutter/lib/src/native/factory_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import '../../sentry_flutter.dart';
import 'sentry_native_binding.dart';

// This isn't actually called, see SentryFlutter.init()
SentryNativeBinding createBinding(PlatformChecker pc, MethodChannel channel) {
SentryNativeBinding createBinding(PlatformChecker _, MethodChannel __) {
throw UnsupportedError("Native binding is not supported on this platform.");
}
10 changes: 10 additions & 0 deletions flutter/lib/src/native/java/sentry_native_java.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:meta/meta.dart';

import '../sentry_native_channel.dart';

// Note: currently this doesn't do anything. Later, it shall be used with
// generated JNI bindings. See https://github.com/getsentry/sentry-dart/issues/1444
@internal
class SentryNativeJava extends SentryNativeChannel {
SentryNativeJava(super.channel);
}
5 changes: 5 additions & 0 deletions flutter/lib/src/native/sentry_native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class SentryNative {
/// Flag indicating if app start measurement was added to the first transaction.
bool didAddAppStartMeasurement = false;

Future<void> init(SentryFlutterOptions options) async =>
_invoke("init", () => _binding.init(options));

Future<void> close() async => _invoke("close", _binding.close);

/// Fetch [NativeAppStart] from native channels. Can only be called once.
Future<NativeAppStart?> fetchNativeAppStart() async {
_didFetchAppStart = true;
Expand Down
3 changes: 3 additions & 0 deletions flutter/lib/src/native/sentry_native_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import 'sentry_native.dart';
@internal
abstract class SentryNativeBinding {
// TODO Move other native calls here.
Future<void> init(SentryFlutterOptions options);

Future<void> close();

Future<NativeAppStart?> fetchNativeAppStart();

Expand Down
43 changes: 43 additions & 0 deletions flutter/lib/src/native/sentry_native_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,49 @@ class SentryNativeChannel implements SentryNativeBinding {

// TODO Move other native calls here.

@override
Future<void> init(SentryFlutterOptions options) async =>
_channel.invokeMethod('initNativeSdk', <String, dynamic>{
'dsn': options.dsn,
'debug': options.debug,
'environment': options.environment,
'release': options.release,
'enableAutoSessionTracking': options.enableAutoSessionTracking,
'enableNativeCrashHandling': options.enableNativeCrashHandling,
'attachStacktrace': options.attachStacktrace,
'attachThreads': options.attachThreads,
'autoSessionTrackingIntervalMillis':
options.autoSessionTrackingInterval.inMilliseconds,
'dist': options.dist,
'integrations': options.sdk.integrations,
'packages':
options.sdk.packages.map((e) => e.toJson()).toList(growable: false),
'diagnosticLevel': options.diagnosticLevel.name,
'maxBreadcrumbs': options.maxBreadcrumbs,
'anrEnabled': options.anrEnabled,
'anrTimeoutIntervalMillis': options.anrTimeoutInterval.inMilliseconds,
'enableAutoNativeBreadcrumbs': options.enableAutoNativeBreadcrumbs,
'maxCacheItems': options.maxCacheItems,
'sendDefaultPii': options.sendDefaultPii,
'enableWatchdogTerminationTracking':
options.enableWatchdogTerminationTracking,
'enableNdkScopeSync': options.enableNdkScopeSync,
'enableAutoPerformanceTracing': options.enableAutoPerformanceTracing,
'sendClientReports': options.sendClientReports,
'proguardUuid': options.proguardUuid,
'maxAttachmentSize': options.maxAttachmentSize,
'recordHttpBreadcrumbs': options.recordHttpBreadcrumbs,
'captureFailedRequests': options.captureFailedRequests,
'enableAppHangTracking': options.enableAppHangTracking,
'connectionTimeoutMillis': options.connectionTimeout.inMilliseconds,
'readTimeoutMillis': options.readTimeout.inMilliseconds,
'appHangTimeoutIntervalMillis':
options.appHangTimeoutInterval.inMilliseconds,
});

@override
Future<void> close() async => _channel.invokeMethod('closeNativeSdk');

@override
Future<NativeAppStart?> fetchNativeAppStart() async {
final json =
Expand Down
4 changes: 2 additions & 2 deletions flutter/lib/src/sentry_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ mixin SentryFlutter {
// The ordering here matters, as we'd like to first start the native integration.
// That allow us to send events to the network and then the Flutter integrations.
// Flutter Web doesn't need that, only Android and iOS.
if (platformChecker.hasNativeIntegration) {
integrations.add(NativeSdkIntegration(channel));
if (_native != null) {
integrations.add(NativeSdkIntegration(_native!));
}

// Will enrich events with device context, native packages and integrations
Expand Down
Loading
Loading