From 5c31a6352ba7020066f562fa29a0ca354d82d148 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 23 Oct 2025 17:16:38 +0200 Subject: [PATCH 01/10] Refactor setContext and removeContext to FFI/JNI --- packages/dart/lib/src/scope_observer.dart | 4 +- .../io/sentry/flutter/SentryFlutterPlugin.kt | 33 - packages/flutter/ffi-cocoa.yaml | 2 + packages/flutter/ffi-jni.yaml | 2 + .../sentry_flutter/SentryFlutterPlugin.swift | 44 - .../flutter/lib/src/native/cocoa/binding.dart | 18 + .../src/native/cocoa/sentry_native_cocoa.dart | 36 + .../flutter/lib/src/native/java/binding.dart | 2522 ++++++++++++++++- .../src/native/java/sentry_native_java.dart | 35 + .../lib/src/native/native_scope_observer.dart | 10 +- .../lib/src/native/sentry_native_channel.dart | 26 +- 11 files changed, 2617 insertions(+), 115 deletions(-) diff --git a/packages/dart/lib/src/scope_observer.dart b/packages/dart/lib/src/scope_observer.dart index dd8dff0767..b01c94e59a 100644 --- a/packages/dart/lib/src/scope_observer.dart +++ b/packages/dart/lib/src/scope_observer.dart @@ -4,8 +4,8 @@ import 'protocol/breadcrumb.dart'; import 'protocol/sentry_user.dart'; abstract class ScopeObserver { - Future setContexts(String key, dynamic value); - Future removeContexts(String key); + FutureOr setContexts(String key, dynamic value); + FutureOr removeContexts(String key); FutureOr setUser(SentryUser? user); FutureOr addBreadcrumb(Breadcrumb breadcrumb); FutureOr clearBreadcrumbs(); diff --git a/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt b/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt index 3a1e12cb79..aad94df0e8 100644 --- a/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt +++ b/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt @@ -61,8 +61,6 @@ class SentryFlutterPlugin : when (call.method) { "initNativeSdk" -> initNativeSdk(call, result) "closeNativeSdk" -> closeNativeSdk(result) - "setContexts" -> setContexts(call.argument("key"), call.argument("value"), result) - "removeContexts" -> removeContexts(call.argument("key"), result) "setExtra" -> setExtra(call.argument("key"), call.argument("value"), result) "removeExtra" -> removeExtra(call.argument("key"), result) "setTag" -> setTag(call.argument("key"), call.argument("value"), result) @@ -141,37 +139,6 @@ class SentryFlutterPlugin : } } - private fun setContexts( - key: String?, - value: Any?, - result: Result, - ) { - if (key == null || value == null) { - result.success("") - return - } - Sentry.configureScope { scope -> - scope.setContexts(key, value) - - result.success("") - } - } - - private fun removeContexts( - key: String?, - result: Result, - ) { - if (key == null) { - result.success("") - return - } - Sentry.configureScope { scope -> - scope.removeContexts(key) - - result.success("") - } - } - private fun setExtra( key: String?, value: String?, diff --git a/packages/flutter/ffi-cocoa.yaml b/packages/flutter/ffi-cocoa.yaml index dba37b1246..45110532e7 100644 --- a/packages/flutter/ffi-cocoa.yaml +++ b/packages/flutter/ffi-cocoa.yaml @@ -38,6 +38,8 @@ objc-interfaces: SentryScope: include: - 'clearBreadcrumbs' + - 'setContextValue:forKey:' + - 'removeContextForKey:' preamble: | // ignore_for_file: type=lint, unused_element diff --git a/packages/flutter/ffi-jni.yaml b/packages/flutter/ffi-jni.yaml index 28727808ea..203493f18d 100644 --- a/packages/flutter/ffi-jni.yaml +++ b/packages/flutter/ffi-jni.yaml @@ -19,5 +19,7 @@ classes: - io.sentry.Sentry - io.sentry.Breadcrumb - io.sentry.ScopesAdapter + - io.sentry.Scope + - io.sentry.ScopeCallback - io.sentry.protocol.User - android.graphics.Bitmap diff --git a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift index 6ac272a72d..146a8dc1d2 100644 --- a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift +++ b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -76,17 +76,6 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { case "closeNativeSdk": closeNativeSdk(call, result: result) - case "setContexts": - let arguments = call.arguments as? [String: Any?] - let key = arguments?["key"] as? String - let value = arguments?["value"] as? Any - setContexts(key: key, value: value, result: result) - - case "removeContexts": - let arguments = call.arguments as? [String: Any?] - let key = arguments?["key"] as? String - removeContexts(key: key, result: result) - case "setExtra": let arguments = call.arguments as? [String: Any?] let key = arguments?["key"] as? String @@ -266,39 +255,6 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { return !name.isEmpty } - private func setContexts(key: String?, value: Any?, result: @escaping FlutterResult) { - guard let key = key else { - result("") - return - } - - SentrySDK.configureScope { scope in - if let dictionary = value as? [String: Any] { - scope.setContext(value: dictionary, key: key) - } else if let string = value as? String { - scope.setContext(value: ["value": string], key: key) - } else if let int = value as? Int { - scope.setContext(value: ["value": int], key: key) - } else if let double = value as? Double { - scope.setContext(value: ["value": double], key: key) - } else if let bool = value as? Bool { - scope.setContext(value: ["value": bool], key: key) - } - result("") - } - } - - private func removeContexts(key: String?, result: @escaping FlutterResult) { - guard let key = key else { - result("") - return - } - SentrySDK.configureScope { scope in - scope.removeContext(key: key) - result("") - } - } - private func setExtra(key: String?, value: Any?, result: @escaping FlutterResult) { guard let key = key else { result("") diff --git a/packages/flutter/lib/src/native/cocoa/binding.dart b/packages/flutter/lib/src/native/cocoa/binding.dart index 0861203419..3119e4c4c9 100644 --- a/packages/flutter/lib/src/native/cocoa/binding.dart +++ b/packages/flutter/lib/src/native/cocoa/binding.dart @@ -1157,6 +1157,10 @@ final _objc_msgSend_1pl9qdv = objc.msgSendPointer .asFunction< void Function( ffi.Pointer, ffi.Pointer)>(); +late final _sel_setContextValue_forKey_ = + objc.registerName("setContextValue:forKey:"); +late final _sel_removeContextForKey_ = + objc.registerName("removeContextForKey:"); /// SentryScope class SentryScope extends objc.NSObject implements SentrySerializable { @@ -1183,6 +1187,20 @@ class SentryScope extends objc.NSObject implements SentrySerializable { void clearBreadcrumbs() { _objc_msgSend_1pl9qdv(this.ref.pointer, _sel_clearBreadcrumbs); } + + /// Sets context values which will overwrite SentryEvent.context when event is + /// "enriched" with scope before sending event. + void setContextValue(objc.NSDictionary value, + {required objc.NSString forKey}) { + _objc_msgSend_pfv6jd(this.ref.pointer, _sel_setContextValue_forKey_, + value.ref.pointer, forKey.ref.pointer); + } + + /// Remove the context for the specified key. + void removeContextForKey(objc.NSString key) { + _objc_msgSend_xtuoz7( + this.ref.pointer, _sel_removeContextForKey_, key.ref.pointer); + } } void _ObjCBlock_ffiVoid_SentryScope_fnPtrTrampoline( diff --git a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart index 89f5de5212..f034c3df83 100644 --- a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart +++ b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart @@ -7,6 +7,7 @@ import '../../../sentry_flutter.dart'; import '../../replay/replay_config.dart'; import '../native_app_start.dart'; import '../sentry_native_channel.dart'; +import '../utils/data_normalizer.dart'; import '../utils/utf8_json.dart'; import 'binding.dart' as cocoa; import 'cocoa_replay_recorder.dart'; @@ -235,6 +236,41 @@ class SentryNativeCocoa extends SentryNativeChannel { cocoa.SentrySDK.setUser(cUser); } }); + + @override + void setContexts(String key, dynamic value) => + tryCatchSync('setContexts', () { + NSDictionary? dictionary; + + final normalizedValue = normalize(value); + dictionary = switch (normalizedValue) { + Map m => _deepConvertMapNonNull(m).toNSDictionary(), + bool b => NSDictionary.fromEntries([ + MapEntry( + 'value'.toNSString(), b ? 1.toNSNumber() : 0.toNSNumber()) + ]), + Object o => NSDictionary.fromEntries( + [MapEntry('value'.toNSString(), toObjCObject(o))]), + _ => null + }; + + cocoa.SentrySDK.configureScope( + cocoa.ObjCBlock_ffiVoid_SentryScope.fromFunction( + (cocoa.SentryScope scope) { + if (dictionary != null) { + scope.setContextValue(dictionary, forKey: key.toNSString()); + } + })); + }); + + @override + void removeContexts(String key) => tryCatchSync('removeContexts', () { + cocoa.SentrySDK.configureScope( + cocoa.ObjCBlock_ffiVoid_SentryScope.fromFunction( + (cocoa.SentryScope scope) { + scope.removeContextForKey(key.toNSString()); + })); + }); } /// This map conversion is needed so we can use the toNSDictionary extension function diff --git a/packages/flutter/lib/src/native/java/binding.dart b/packages/flutter/lib/src/native/java/binding.dart index 63b2a1fc97..949bb60638 100644 --- a/packages/flutter/lib/src/native/java/binding.dart +++ b/packages/flutter/lib/src/native/java/binding.dart @@ -2888,7 +2888,7 @@ class Sentry extends jni$_.JObject { /// The returned object must be released after use, by calling the [release] method. static jni$_.JObject captureEvent$1( jni$_.JObject sentryEvent, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$sentryEvent = sentryEvent.reference; final _$scopeCallback = scopeCallback.reference; @@ -2967,7 +2967,7 @@ class Sentry extends jni$_.JObject { static jni$_.JObject captureEvent$3( jni$_.JObject sentryEvent, jni$_.JObject? hint, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$sentryEvent = sentryEvent.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -3034,7 +3034,7 @@ class Sentry extends jni$_.JObject { /// The returned object must be released after use, by calling the [release] method. static jni$_.JObject captureMessage$1( jni$_.JString string, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$string = string.reference; final _$scopeCallback = scopeCallback.reference; @@ -3113,7 +3113,7 @@ class Sentry extends jni$_.JObject { static jni$_.JObject captureMessage$3( jni$_.JString string, jni$_.JObject sentryLevel, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$string = string.reference; final _$sentryLevel = sentryLevel.reference; @@ -3221,7 +3221,7 @@ class Sentry extends jni$_.JObject { static jni$_.JObject captureFeedback$2( jni$_.JObject feedback, jni$_.JObject? hint, - jni$_.JObject? scopeCallback, + ScopeCallback? scopeCallback, ) { final _$feedback = feedback.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -3288,7 +3288,7 @@ class Sentry extends jni$_.JObject { /// The returned object must be released after use, by calling the [release] method. static jni$_.JObject captureException$1( jni$_.JObject throwable, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$throwable = throwable.reference; final _$scopeCallback = scopeCallback.reference; @@ -3367,7 +3367,7 @@ class Sentry extends jni$_.JObject { static jni$_.JObject captureException$3( jni$_.JObject throwable, jni$_.JObject? hint, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$throwable = throwable.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -3899,7 +3899,7 @@ class Sentry extends jni$_.JObject { /// from: `static public void withScope(io.sentry.ScopeCallback scopeCallback)` static void withScope( - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeCallback = scopeCallback.reference; _withScope(_class.reference.pointer, _id_withScope as jni$_.JMethodIDPtr, @@ -3925,7 +3925,7 @@ class Sentry extends jni$_.JObject { /// from: `static public void withIsolationScope(io.sentry.ScopeCallback scopeCallback)` static void withIsolationScope( - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeCallback = scopeCallback.reference; _withIsolationScope( @@ -3953,7 +3953,7 @@ class Sentry extends jni$_.JObject { /// from: `static public void configureScope(io.sentry.ScopeCallback scopeCallback)` static void configureScope( - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeCallback = scopeCallback.reference; _configureScope(_class.reference.pointer, @@ -3986,7 +3986,7 @@ class Sentry extends jni$_.JObject { /// from: `static public void configureScope(io.sentry.ScopeType scopeType, io.sentry.ScopeCallback scopeCallback)` static void configureScope$1( jni$_.JObject? scopeType, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeType = scopeType?.reference ?? jni$_.jNullReference; final _$scopeCallback = scopeCallback.reference; @@ -6631,7 +6631,7 @@ class ScopesAdapter extends jni$_.JObject { jni$_.JObject captureEvent$1( jni$_.JObject sentryEvent, jni$_.JObject? hint, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$sentryEvent = sentryEvent.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -6712,7 +6712,7 @@ class ScopesAdapter extends jni$_.JObject { jni$_.JObject captureMessage$1( jni$_.JString string, jni$_.JObject sentryLevel, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$string = string.reference; final _$sentryLevel = sentryLevel.reference; @@ -6820,7 +6820,7 @@ class ScopesAdapter extends jni$_.JObject { jni$_.JObject captureFeedback$2( jni$_.JObject feedback, jni$_.JObject? hint, - jni$_.JObject? scopeCallback, + ScopeCallback? scopeCallback, ) { final _$feedback = feedback.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -6939,7 +6939,7 @@ class ScopesAdapter extends jni$_.JObject { jni$_.JObject captureException$1( jni$_.JObject throwable, jni$_.JObject? hint, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$throwable = throwable.reference; final _$hint = hint?.reference ?? jni$_.jNullReference; @@ -7494,7 +7494,7 @@ class ScopesAdapter extends jni$_.JObject { /// from: `public void withScope(io.sentry.ScopeCallback scopeCallback)` void withScope( - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeCallback = scopeCallback.reference; _withScope(reference.pointer, _id_withScope as jni$_.JMethodIDPtr, @@ -7520,7 +7520,7 @@ class ScopesAdapter extends jni$_.JObject { /// from: `public void withIsolationScope(io.sentry.ScopeCallback scopeCallback)` void withIsolationScope( - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeCallback = scopeCallback.reference; _withIsolationScope( @@ -7555,7 +7555,7 @@ class ScopesAdapter extends jni$_.JObject { /// from: `public void configureScope(io.sentry.ScopeType scopeType, io.sentry.ScopeCallback scopeCallback)` void configureScope( jni$_.JObject? scopeType, - jni$_.JObject scopeCallback, + ScopeCallback scopeCallback, ) { final _$scopeType = scopeType?.reference ?? jni$_.jNullReference; final _$scopeCallback = scopeCallback.reference; @@ -8514,6 +8514,2492 @@ final class $ScopesAdapter$Type extends jni$_.JObjType { } } +/// from: `io.sentry.Scope$IWithPropagationContext` +class Scope$IWithPropagationContext extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + Scope$IWithPropagationContext.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = + jni$_.JClass.forName(r'io/sentry/Scope$IWithPropagationContext'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $Scope$IWithPropagationContext$NullableType(); + static const type = $Scope$IWithPropagationContext$Type(); + static final _id_accept = _class.instanceMethodId( + r'accept', + r'(Lio/sentry/PropagationContext;)V', + ); + + static final _accept = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public abstract void accept(io.sentry.PropagationContext propagationContext)` + void accept( + jni$_.JObject propagationContext, + ) { + final _$propagationContext = propagationContext.reference; + _accept(reference.pointer, _id_accept as jni$_.JMethodIDPtr, + _$propagationContext.pointer) + .check(); + } + + /// Maps a specific port to the implemented interface. + static final core$_.Map _$impls = {}; + static jni$_.JObjectPtr _$invoke( + int port, + jni$_.JObjectPtr descriptor, + jni$_.JObjectPtr args, + ) { + return _$invokeMethod( + port, + jni$_.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final jni$_.Pointer< + jni$_.NativeFunction< + jni$_.JObjectPtr Function( + jni$_.Int64, jni$_.JObjectPtr, jni$_.JObjectPtr)>> + _$invokePointer = jni$_.Pointer.fromFunction(_$invoke); + + static jni$_.Pointer _$invokeMethod( + int $p, + jni$_.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == r'accept(Lio/sentry/PropagationContext;)V') { + _$impls[$p]!.accept( + $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), + ); + return jni$_.nullptr; + } + } catch (e) { + return jni$_.ProtectedJniExtensions.newDartException(e); + } + return jni$_.nullptr; + } + + static void implementIn( + jni$_.JImplementer implementer, + $Scope$IWithPropagationContext $impl, + ) { + late final jni$_.RawReceivePort $p; + $p = jni$_.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = jni$_.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + jni$_.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'io.sentry.Scope$IWithPropagationContext', + $p, + _$invokePointer, + [ + if ($impl.accept$async) r'accept(Lio/sentry/PropagationContext;)V', + ], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory Scope$IWithPropagationContext.implement( + $Scope$IWithPropagationContext $impl, + ) { + final $i = jni$_.JImplementer(); + implementIn($i, $impl); + return Scope$IWithPropagationContext.fromReference( + $i.implementReference(), + ); + } +} + +abstract base mixin class $Scope$IWithPropagationContext { + factory $Scope$IWithPropagationContext({ + required void Function(jni$_.JObject propagationContext) accept, + bool accept$async, + }) = _$Scope$IWithPropagationContext; + + void accept(jni$_.JObject propagationContext); + bool get accept$async => false; +} + +final class _$Scope$IWithPropagationContext + with $Scope$IWithPropagationContext { + _$Scope$IWithPropagationContext({ + required void Function(jni$_.JObject propagationContext) accept, + this.accept$async = false, + }) : _accept = accept; + + final void Function(jni$_.JObject propagationContext) _accept; + final bool accept$async; + + void accept(jni$_.JObject propagationContext) { + return _accept(propagationContext); + } +} + +final class $Scope$IWithPropagationContext$NullableType + extends jni$_.JObjType { + @jni$_.internal + const $Scope$IWithPropagationContext$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope$IWithPropagationContext;'; + + @jni$_.internal + @core$_.override + Scope$IWithPropagationContext? fromReference(jni$_.JReference reference) => + reference.isNull + ? null + : Scope$IWithPropagationContext.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => this; + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$IWithPropagationContext$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$IWithPropagationContext$NullableType) && + other is $Scope$IWithPropagationContext$NullableType; + } +} + +final class $Scope$IWithPropagationContext$Type + extends jni$_.JObjType { + @jni$_.internal + const $Scope$IWithPropagationContext$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope$IWithPropagationContext;'; + + @jni$_.internal + @core$_.override + Scope$IWithPropagationContext fromReference(jni$_.JReference reference) => + Scope$IWithPropagationContext.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $Scope$IWithPropagationContext$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$IWithPropagationContext$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$IWithPropagationContext$Type) && + other is $Scope$IWithPropagationContext$Type; + } +} + +/// from: `io.sentry.Scope$IWithTransaction` +class Scope$IWithTransaction extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + Scope$IWithTransaction.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = + jni$_.JClass.forName(r'io/sentry/Scope$IWithTransaction'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $Scope$IWithTransaction$NullableType(); + static const type = $Scope$IWithTransaction$Type(); + static final _id_accept = _class.instanceMethodId( + r'accept', + r'(Lio/sentry/ITransaction;)V', + ); + + static final _accept = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public abstract void accept(io.sentry.ITransaction iTransaction)` + void accept( + jni$_.JObject? iTransaction, + ) { + final _$iTransaction = iTransaction?.reference ?? jni$_.jNullReference; + _accept(reference.pointer, _id_accept as jni$_.JMethodIDPtr, + _$iTransaction.pointer) + .check(); + } + + /// Maps a specific port to the implemented interface. + static final core$_.Map _$impls = {}; + static jni$_.JObjectPtr _$invoke( + int port, + jni$_.JObjectPtr descriptor, + jni$_.JObjectPtr args, + ) { + return _$invokeMethod( + port, + jni$_.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final jni$_.Pointer< + jni$_.NativeFunction< + jni$_.JObjectPtr Function( + jni$_.Int64, jni$_.JObjectPtr, jni$_.JObjectPtr)>> + _$invokePointer = jni$_.Pointer.fromFunction(_$invoke); + + static jni$_.Pointer _$invokeMethod( + int $p, + jni$_.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == r'accept(Lio/sentry/ITransaction;)V') { + _$impls[$p]!.accept( + $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true), + ); + return jni$_.nullptr; + } + } catch (e) { + return jni$_.ProtectedJniExtensions.newDartException(e); + } + return jni$_.nullptr; + } + + static void implementIn( + jni$_.JImplementer implementer, + $Scope$IWithTransaction $impl, + ) { + late final jni$_.RawReceivePort $p; + $p = jni$_.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = jni$_.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + jni$_.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'io.sentry.Scope$IWithTransaction', + $p, + _$invokePointer, + [ + if ($impl.accept$async) r'accept(Lio/sentry/ITransaction;)V', + ], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory Scope$IWithTransaction.implement( + $Scope$IWithTransaction $impl, + ) { + final $i = jni$_.JImplementer(); + implementIn($i, $impl); + return Scope$IWithTransaction.fromReference( + $i.implementReference(), + ); + } +} + +abstract base mixin class $Scope$IWithTransaction { + factory $Scope$IWithTransaction({ + required void Function(jni$_.JObject? iTransaction) accept, + bool accept$async, + }) = _$Scope$IWithTransaction; + + void accept(jni$_.JObject? iTransaction); + bool get accept$async => false; +} + +final class _$Scope$IWithTransaction with $Scope$IWithTransaction { + _$Scope$IWithTransaction({ + required void Function(jni$_.JObject? iTransaction) accept, + this.accept$async = false, + }) : _accept = accept; + + final void Function(jni$_.JObject? iTransaction) _accept; + final bool accept$async; + + void accept(jni$_.JObject? iTransaction) { + return _accept(iTransaction); + } +} + +final class $Scope$IWithTransaction$NullableType + extends jni$_.JObjType { + @jni$_.internal + const $Scope$IWithTransaction$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope$IWithTransaction;'; + + @jni$_.internal + @core$_.override + Scope$IWithTransaction? fromReference(jni$_.JReference reference) => + reference.isNull + ? null + : Scope$IWithTransaction.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => this; + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$IWithTransaction$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$IWithTransaction$NullableType) && + other is $Scope$IWithTransaction$NullableType; + } +} + +final class $Scope$IWithTransaction$Type + extends jni$_.JObjType { + @jni$_.internal + const $Scope$IWithTransaction$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope$IWithTransaction;'; + + @jni$_.internal + @core$_.override + Scope$IWithTransaction fromReference(jni$_.JReference reference) => + Scope$IWithTransaction.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $Scope$IWithTransaction$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$IWithTransaction$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$IWithTransaction$Type) && + other is $Scope$IWithTransaction$Type; + } +} + +/// from: `io.sentry.Scope` +class Scope extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + Scope.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = jni$_.JClass.forName(r'io/sentry/Scope'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $Scope$NullableType(); + static const type = $Scope$Type(); + static final _id_new$ = _class.constructorId( + r'(Lio/sentry/SentryOptions;)V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void (io.sentry.SentryOptions sentryOptions)` + /// The returned object must be released after use, by calling the [release] method. + factory Scope( + jni$_.JObject sentryOptions, + ) { + final _$sentryOptions = sentryOptions.reference; + return Scope.fromReference(_new$(_class.reference.pointer, + _id_new$ as jni$_.JMethodIDPtr, _$sentryOptions.pointer) + .reference); + } + + static final _id_getLevel = _class.instanceMethodId( + r'getLevel', + r'()Lio/sentry/SentryLevel;', + ); + + static final _getLevel = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.SentryLevel getLevel()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getLevel() { + return _getLevel(reference.pointer, _id_getLevel as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_setLevel = _class.instanceMethodId( + r'setLevel', + r'(Lio/sentry/SentryLevel;)V', + ); + + static final _setLevel = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setLevel(io.sentry.SentryLevel sentryLevel)` + void setLevel( + jni$_.JObject? sentryLevel, + ) { + final _$sentryLevel = sentryLevel?.reference ?? jni$_.jNullReference; + _setLevel(reference.pointer, _id_setLevel as jni$_.JMethodIDPtr, + _$sentryLevel.pointer) + .check(); + } + + static final _id_getTransactionName = _class.instanceMethodId( + r'getTransactionName', + r'()Ljava/lang/String;', + ); + + static final _getTransactionName = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.lang.String getTransactionName()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getTransactionName() { + return _getTransactionName( + reference.pointer, _id_getTransactionName as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); + } + + static final _id_setTransaction = _class.instanceMethodId( + r'setTransaction', + r'(Ljava/lang/String;)V', + ); + + static final _setTransaction = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setTransaction(java.lang.String string)` + void setTransaction( + jni$_.JString string, + ) { + final _$string = string.reference; + _setTransaction(reference.pointer, _id_setTransaction as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); + } + + static final _id_getSpan = _class.instanceMethodId( + r'getSpan', + r'()Lio/sentry/ISpan;', + ); + + static final _getSpan = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.ISpan getSpan()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getSpan() { + return _getSpan(reference.pointer, _id_getSpan as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_setActiveSpan = _class.instanceMethodId( + r'setActiveSpan', + r'(Lio/sentry/ISpan;)V', + ); + + static final _setActiveSpan = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setActiveSpan(io.sentry.ISpan iSpan)` + void setActiveSpan( + jni$_.JObject? iSpan, + ) { + final _$iSpan = iSpan?.reference ?? jni$_.jNullReference; + _setActiveSpan(reference.pointer, _id_setActiveSpan as jni$_.JMethodIDPtr, + _$iSpan.pointer) + .check(); + } + + static final _id_setTransaction$1 = _class.instanceMethodId( + r'setTransaction', + r'(Lio/sentry/ITransaction;)V', + ); + + static final _setTransaction$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setTransaction(io.sentry.ITransaction iTransaction)` + void setTransaction$1( + jni$_.JObject? iTransaction, + ) { + final _$iTransaction = iTransaction?.reference ?? jni$_.jNullReference; + _setTransaction$1(reference.pointer, + _id_setTransaction$1 as jni$_.JMethodIDPtr, _$iTransaction.pointer) + .check(); + } + + static final _id_getUser = _class.instanceMethodId( + r'getUser', + r'()Lio/sentry/protocol/User;', + ); + + static final _getUser = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.protocol.User getUser()` + /// The returned object must be released after use, by calling the [release] method. + User? getUser() { + return _getUser(reference.pointer, _id_getUser as jni$_.JMethodIDPtr) + .object(const $User$NullableType()); + } + + static final _id_setUser = _class.instanceMethodId( + r'setUser', + r'(Lio/sentry/protocol/User;)V', + ); + + static final _setUser = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setUser(io.sentry.protocol.User user)` + void setUser( + User? user, + ) { + final _$user = user?.reference ?? jni$_.jNullReference; + _setUser(reference.pointer, _id_setUser as jni$_.JMethodIDPtr, + _$user.pointer) + .check(); + } + + static final _id_getScreen = _class.instanceMethodId( + r'getScreen', + r'()Ljava/lang/String;', + ); + + static final _getScreen = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.lang.String getScreen()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getScreen() { + return _getScreen(reference.pointer, _id_getScreen as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); + } + + static final _id_setScreen = _class.instanceMethodId( + r'setScreen', + r'(Ljava/lang/String;)V', + ); + + static final _setScreen = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setScreen(java.lang.String string)` + void setScreen( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + _setScreen(reference.pointer, _id_setScreen as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); + } + + static final _id_getReplayId = _class.instanceMethodId( + r'getReplayId', + r'()Lio/sentry/protocol/SentryId;', + ); + + static final _getReplayId = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.protocol.SentryId getReplayId()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getReplayId() { + return _getReplayId( + reference.pointer, _id_getReplayId as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_setReplayId = _class.instanceMethodId( + r'setReplayId', + r'(Lio/sentry/protocol/SentryId;)V', + ); + + static final _setReplayId = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setReplayId(io.sentry.protocol.SentryId sentryId)` + void setReplayId( + jni$_.JObject sentryId, + ) { + final _$sentryId = sentryId.reference; + _setReplayId(reference.pointer, _id_setReplayId as jni$_.JMethodIDPtr, + _$sentryId.pointer) + .check(); + } + + static final _id_getRequest = _class.instanceMethodId( + r'getRequest', + r'()Lio/sentry/protocol/Request;', + ); + + static final _getRequest = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.protocol.Request getRequest()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getRequest() { + return _getRequest(reference.pointer, _id_getRequest as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_setRequest = _class.instanceMethodId( + r'setRequest', + r'(Lio/sentry/protocol/Request;)V', + ); + + static final _setRequest = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setRequest(io.sentry.protocol.Request request)` + void setRequest( + jni$_.JObject? request, + ) { + final _$request = request?.reference ?? jni$_.jNullReference; + _setRequest(reference.pointer, _id_setRequest as jni$_.JMethodIDPtr, + _$request.pointer) + .check(); + } + + static final _id_getFingerprint = _class.instanceMethodId( + r'getFingerprint', + r'()Ljava/util/List;', + ); + + static final _getFingerprint = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.List getFingerprint()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JList getFingerprint() { + return _getFingerprint( + reference.pointer, _id_getFingerprint as jni$_.JMethodIDPtr) + .object>( + const jni$_.JListType(jni$_.JStringNullableType())); + } + + static final _id_setFingerprint = _class.instanceMethodId( + r'setFingerprint', + r'(Ljava/util/List;)V', + ); + + static final _setFingerprint = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setFingerprint(java.util.List list)` + void setFingerprint( + jni$_.JList list, + ) { + final _$list = list.reference; + _setFingerprint(reference.pointer, _id_setFingerprint as jni$_.JMethodIDPtr, + _$list.pointer) + .check(); + } + + static final _id_getBreadcrumbs = _class.instanceMethodId( + r'getBreadcrumbs', + r'()Ljava/util/Queue;', + ); + + static final _getBreadcrumbs = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.Queue getBreadcrumbs()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getBreadcrumbs() { + return _getBreadcrumbs( + reference.pointer, _id_getBreadcrumbs as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_addBreadcrumb = _class.instanceMethodId( + r'addBreadcrumb', + r'(Lio/sentry/Breadcrumb;Lio/sentry/Hint;)V', + ); + + static final _addBreadcrumb = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void addBreadcrumb(io.sentry.Breadcrumb breadcrumb, io.sentry.Hint hint)` + void addBreadcrumb( + Breadcrumb breadcrumb, + jni$_.JObject? hint, + ) { + final _$breadcrumb = breadcrumb.reference; + final _$hint = hint?.reference ?? jni$_.jNullReference; + _addBreadcrumb(reference.pointer, _id_addBreadcrumb as jni$_.JMethodIDPtr, + _$breadcrumb.pointer, _$hint.pointer) + .check(); + } + + static final _id_addBreadcrumb$1 = _class.instanceMethodId( + r'addBreadcrumb', + r'(Lio/sentry/Breadcrumb;)V', + ); + + static final _addBreadcrumb$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void addBreadcrumb(io.sentry.Breadcrumb breadcrumb)` + void addBreadcrumb$1( + Breadcrumb breadcrumb, + ) { + final _$breadcrumb = breadcrumb.reference; + _addBreadcrumb$1(reference.pointer, + _id_addBreadcrumb$1 as jni$_.JMethodIDPtr, _$breadcrumb.pointer) + .check(); + } + + static final _id_clearBreadcrumbs = _class.instanceMethodId( + r'clearBreadcrumbs', + r'()V', + ); + + static final _clearBreadcrumbs = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void clearBreadcrumbs()` + void clearBreadcrumbs() { + _clearBreadcrumbs( + reference.pointer, _id_clearBreadcrumbs as jni$_.JMethodIDPtr) + .check(); + } + + static final _id_clearTransaction = _class.instanceMethodId( + r'clearTransaction', + r'()V', + ); + + static final _clearTransaction = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void clearTransaction()` + void clearTransaction() { + _clearTransaction( + reference.pointer, _id_clearTransaction as jni$_.JMethodIDPtr) + .check(); + } + + static final _id_getTransaction = _class.instanceMethodId( + r'getTransaction', + r'()Lio/sentry/ITransaction;', + ); + + static final _getTransaction = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.ITransaction getTransaction()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getTransaction() { + return _getTransaction( + reference.pointer, _id_getTransaction as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_clear = _class.instanceMethodId( + r'clear', + r'()V', + ); + + static final _clear = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void clear()` + void clear() { + _clear(reference.pointer, _id_clear as jni$_.JMethodIDPtr).check(); + } + + static final _id_getTags = _class.instanceMethodId( + r'getTags', + r'()Ljava/util/Map;', + ); + + static final _getTags = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.Map getTags()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JMap getTags() { + return _getTags(reference.pointer, _id_getTags as jni$_.JMethodIDPtr) + .object>( + const jni$_.JMapType( + jni$_.JStringNullableType(), jni$_.JStringNullableType())); + } + + static final _id_setTag = _class.instanceMethodId( + r'setTag', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _setTag = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setTag(java.lang.String string, java.lang.String string1)` + void setTag( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _setTag(reference.pointer, _id_setTag as jni$_.JMethodIDPtr, + _$string.pointer, _$string1.pointer) + .check(); + } + + static final _id_removeTag = _class.instanceMethodId( + r'removeTag', + r'(Ljava/lang/String;)V', + ); + + static final _removeTag = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void removeTag(java.lang.String string)` + void removeTag( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + _removeTag(reference.pointer, _id_removeTag as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); + } + + static final _id_getExtras = _class.instanceMethodId( + r'getExtras', + r'()Ljava/util/Map;', + ); + + static final _getExtras = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.Map getExtras()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JMap getExtras() { + return _getExtras(reference.pointer, _id_getExtras as jni$_.JMethodIDPtr) + .object>( + const jni$_.JMapType( + jni$_.JStringNullableType(), jni$_.JObjectNullableType())); + } + + static final _id_setExtra = _class.instanceMethodId( + r'setExtra', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _setExtra = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setExtra(java.lang.String string, java.lang.String string1)` + void setExtra( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _setExtra(reference.pointer, _id_setExtra as jni$_.JMethodIDPtr, + _$string.pointer, _$string1.pointer) + .check(); + } + + static final _id_removeExtra = _class.instanceMethodId( + r'removeExtra', + r'(Ljava/lang/String;)V', + ); + + static final _removeExtra = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void removeExtra(java.lang.String string)` + void removeExtra( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + _removeExtra(reference.pointer, _id_removeExtra as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); + } + + static final _id_getContexts = _class.instanceMethodId( + r'getContexts', + r'()Lio/sentry/protocol/Contexts;', + ); + + static final _getContexts = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.protocol.Contexts getContexts()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getContexts() { + return _getContexts( + reference.pointer, _id_getContexts as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_setContexts = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/lang/Object;)V', + ); + + static final _setContexts = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.Object object)` + void setContexts( + jni$_.JString? string, + jni$_.JObject? object, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$object = object?.reference ?? jni$_.jNullReference; + _setContexts(reference.pointer, _id_setContexts as jni$_.JMethodIDPtr, + _$string.pointer, _$object.pointer) + .check(); + } + + static final _id_setContexts$1 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/lang/Boolean;)V', + ); + + static final _setContexts$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.Boolean boolean)` + void setContexts$1( + jni$_.JString? string, + jni$_.JBoolean? boolean, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$boolean = boolean?.reference ?? jni$_.jNullReference; + _setContexts$1(reference.pointer, _id_setContexts$1 as jni$_.JMethodIDPtr, + _$string.pointer, _$boolean.pointer) + .check(); + } + + static final _id_setContexts$2 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _setContexts$2 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.String string1)` + void setContexts$2( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _setContexts$2(reference.pointer, _id_setContexts$2 as jni$_.JMethodIDPtr, + _$string.pointer, _$string1.pointer) + .check(); + } + + static final _id_setContexts$3 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/lang/Number;)V', + ); + + static final _setContexts$3 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.Number number)` + void setContexts$3( + jni$_.JString? string, + jni$_.JNumber? number, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$number = number?.reference ?? jni$_.jNullReference; + _setContexts$3(reference.pointer, _id_setContexts$3 as jni$_.JMethodIDPtr, + _$string.pointer, _$number.pointer) + .check(); + } + + static final _id_setContexts$4 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/util/Collection;)V', + ); + + static final _setContexts$4 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.util.Collection collection)` + void setContexts$4( + jni$_.JString? string, + jni$_.JObject? collection, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$collection = collection?.reference ?? jni$_.jNullReference; + _setContexts$4(reference.pointer, _id_setContexts$4 as jni$_.JMethodIDPtr, + _$string.pointer, _$collection.pointer) + .check(); + } + + static final _id_setContexts$5 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;[Ljava/lang/Object;)V', + ); + + static final _setContexts$5 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.Object[] objects)` + void setContexts$5( + jni$_.JString? string, + jni$_.JArray? objects, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$objects = objects?.reference ?? jni$_.jNullReference; + _setContexts$5(reference.pointer, _id_setContexts$5 as jni$_.JMethodIDPtr, + _$string.pointer, _$objects.pointer) + .check(); + } + + static final _id_setContexts$6 = _class.instanceMethodId( + r'setContexts', + r'(Ljava/lang/String;Ljava/lang/Character;)V', + ); + + static final _setContexts$6 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setContexts(java.lang.String string, java.lang.Character character)` + void setContexts$6( + jni$_.JString? string, + jni$_.JCharacter? character, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$character = character?.reference ?? jni$_.jNullReference; + _setContexts$6(reference.pointer, _id_setContexts$6 as jni$_.JMethodIDPtr, + _$string.pointer, _$character.pointer) + .check(); + } + + static final _id_removeContexts = _class.instanceMethodId( + r'removeContexts', + r'(Ljava/lang/String;)V', + ); + + static final _removeContexts = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void removeContexts(java.lang.String string)` + void removeContexts( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + _removeContexts(reference.pointer, _id_removeContexts as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); + } + + static final _id_getAttachments = _class.instanceMethodId( + r'getAttachments', + r'()Ljava/util/List;', + ); + + static final _getAttachments = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.List getAttachments()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JList getAttachments() { + return _getAttachments( + reference.pointer, _id_getAttachments as jni$_.JMethodIDPtr) + .object>( + const jni$_.JListType(jni$_.JObjectNullableType())); + } + + static final _id_addAttachment = _class.instanceMethodId( + r'addAttachment', + r'(Lio/sentry/Attachment;)V', + ); + + static final _addAttachment = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void addAttachment(io.sentry.Attachment attachment)` + void addAttachment( + jni$_.JObject attachment, + ) { + final _$attachment = attachment.reference; + _addAttachment(reference.pointer, _id_addAttachment as jni$_.JMethodIDPtr, + _$attachment.pointer) + .check(); + } + + static final _id_clearAttachments = _class.instanceMethodId( + r'clearAttachments', + r'()V', + ); + + static final _clearAttachments = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void clearAttachments()` + void clearAttachments() { + _clearAttachments( + reference.pointer, _id_clearAttachments as jni$_.JMethodIDPtr) + .check(); + } + + static final _id_getEventProcessors = _class.instanceMethodId( + r'getEventProcessors', + r'()Ljava/util/List;', + ); + + static final _getEventProcessors = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.List getEventProcessors()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JList getEventProcessors() { + return _getEventProcessors( + reference.pointer, _id_getEventProcessors as jni$_.JMethodIDPtr) + .object>( + const jni$_.JListType(jni$_.JObjectNullableType())); + } + + static final _id_getEventProcessorsWithOrder = _class.instanceMethodId( + r'getEventProcessorsWithOrder', + r'()Ljava/util/List;', + ); + + static final _getEventProcessorsWithOrder = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public java.util.List getEventProcessorsWithOrder()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JList getEventProcessorsWithOrder() { + return _getEventProcessorsWithOrder(reference.pointer, + _id_getEventProcessorsWithOrder as jni$_.JMethodIDPtr) + .object>( + const jni$_.JListType(jni$_.JObjectNullableType())); + } + + static final _id_addEventProcessor = _class.instanceMethodId( + r'addEventProcessor', + r'(Lio/sentry/EventProcessor;)V', + ); + + static final _addEventProcessor = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void addEventProcessor(io.sentry.EventProcessor eventProcessor)` + void addEventProcessor( + jni$_.JObject eventProcessor, + ) { + final _$eventProcessor = eventProcessor.reference; + _addEventProcessor( + reference.pointer, + _id_addEventProcessor as jni$_.JMethodIDPtr, + _$eventProcessor.pointer) + .check(); + } + + static final _id_withSession = _class.instanceMethodId( + r'withSession', + r'(Lio/sentry/Scope$IWithSession;)Lio/sentry/Session;', + ); + + static final _withSession = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public io.sentry.Session withSession(io.sentry.Scope$IWithSession iWithSession)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? withSession( + jni$_.JObject iWithSession, + ) { + final _$iWithSession = iWithSession.reference; + return _withSession(reference.pointer, + _id_withSession as jni$_.JMethodIDPtr, _$iWithSession.pointer) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_startSession = _class.instanceMethodId( + r'startSession', + r'()Lio/sentry/Scope$SessionPair;', + ); + + static final _startSession = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.Scope$SessionPair startSession()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? startSession() { + return _startSession( + reference.pointer, _id_startSession as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_endSession = _class.instanceMethodId( + r'endSession', + r'()Lio/sentry/Session;', + ); + + static final _endSession = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.Session endSession()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? endSession() { + return _endSession(reference.pointer, _id_endSession as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_withTransaction = _class.instanceMethodId( + r'withTransaction', + r'(Lio/sentry/Scope$IWithTransaction;)V', + ); + + static final _withTransaction = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void withTransaction(io.sentry.Scope$IWithTransaction iWithTransaction)` + void withTransaction( + Scope$IWithTransaction iWithTransaction, + ) { + final _$iWithTransaction = iWithTransaction.reference; + _withTransaction( + reference.pointer, + _id_withTransaction as jni$_.JMethodIDPtr, + _$iWithTransaction.pointer) + .check(); + } + + static final _id_getOptions = _class.instanceMethodId( + r'getOptions', + r'()Lio/sentry/SentryOptions;', + ); + + static final _getOptions = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.SentryOptions getOptions()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getOptions() { + return _getOptions(reference.pointer, _id_getOptions as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_getSession = _class.instanceMethodId( + r'getSession', + r'()Lio/sentry/Session;', + ); + + static final _getSession = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.Session getSession()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getSession() { + return _getSession(reference.pointer, _id_getSession as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_clearSession = _class.instanceMethodId( + r'clearSession', + r'()V', + ); + + static final _clearSession = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void clearSession()` + void clearSession() { + _clearSession(reference.pointer, _id_clearSession as jni$_.JMethodIDPtr) + .check(); + } + + static final _id_setPropagationContext = _class.instanceMethodId( + r'setPropagationContext', + r'(Lio/sentry/PropagationContext;)V', + ); + + static final _setPropagationContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setPropagationContext(io.sentry.PropagationContext propagationContext)` + void setPropagationContext( + jni$_.JObject propagationContext, + ) { + final _$propagationContext = propagationContext.reference; + _setPropagationContext( + reference.pointer, + _id_setPropagationContext as jni$_.JMethodIDPtr, + _$propagationContext.pointer) + .check(); + } + + static final _id_getPropagationContext = _class.instanceMethodId( + r'getPropagationContext', + r'()Lio/sentry/PropagationContext;', + ); + + static final _getPropagationContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.PropagationContext getPropagationContext()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getPropagationContext() { + return _getPropagationContext( + reference.pointer, _id_getPropagationContext as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_withPropagationContext = _class.instanceMethodId( + r'withPropagationContext', + r'(Lio/sentry/Scope$IWithPropagationContext;)Lio/sentry/PropagationContext;', + ); + + static final _withPropagationContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public io.sentry.PropagationContext withPropagationContext(io.sentry.Scope$IWithPropagationContext iWithPropagationContext)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject withPropagationContext( + Scope$IWithPropagationContext iWithPropagationContext, + ) { + final _$iWithPropagationContext = iWithPropagationContext.reference; + return _withPropagationContext( + reference.pointer, + _id_withPropagationContext as jni$_.JMethodIDPtr, + _$iWithPropagationContext.pointer) + .object(const jni$_.JObjectType()); + } + + static final _id_clone = _class.instanceMethodId( + r'clone', + r'()Lio/sentry/IScope;', + ); + + static final _clone = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.IScope clone()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject clone() { + return _clone(reference.pointer, _id_clone as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_setLastEventId = _class.instanceMethodId( + r'setLastEventId', + r'(Lio/sentry/protocol/SentryId;)V', + ); + + static final _setLastEventId = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void setLastEventId(io.sentry.protocol.SentryId sentryId)` + void setLastEventId( + jni$_.JObject sentryId, + ) { + final _$sentryId = sentryId.reference; + _setLastEventId(reference.pointer, _id_setLastEventId as jni$_.JMethodIDPtr, + _$sentryId.pointer) + .check(); + } + + static final _id_getLastEventId = _class.instanceMethodId( + r'getLastEventId', + r'()Lio/sentry/protocol/SentryId;', + ); + + static final _getLastEventId = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.protocol.SentryId getLastEventId()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getLastEventId() { + return _getLastEventId( + reference.pointer, _id_getLastEventId as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_bindClient = _class.instanceMethodId( + r'bindClient', + r'(Lio/sentry/ISentryClient;)V', + ); + + static final _bindClient = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void bindClient(io.sentry.ISentryClient iSentryClient)` + void bindClient( + jni$_.JObject iSentryClient, + ) { + final _$iSentryClient = iSentryClient.reference; + _bindClient(reference.pointer, _id_bindClient as jni$_.JMethodIDPtr, + _$iSentryClient.pointer) + .check(); + } + + static final _id_getClient = _class.instanceMethodId( + r'getClient', + r'()Lio/sentry/ISentryClient;', + ); + + static final _getClient = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public io.sentry.ISentryClient getClient()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getClient() { + return _getClient(reference.pointer, _id_getClient as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_assignTraceContext = _class.instanceMethodId( + r'assignTraceContext', + r'(Lio/sentry/SentryEvent;)V', + ); + + static final _assignTraceContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void assignTraceContext(io.sentry.SentryEvent sentryEvent)` + void assignTraceContext( + jni$_.JObject sentryEvent, + ) { + final _$sentryEvent = sentryEvent.reference; + _assignTraceContext(reference.pointer, + _id_assignTraceContext as jni$_.JMethodIDPtr, _$sentryEvent.pointer) + .check(); + } + + static final _id_setSpanContext = _class.instanceMethodId( + r'setSpanContext', + r'(Ljava/lang/Throwable;Lio/sentry/ISpan;Ljava/lang/String;)V', + ); + + static final _setSpanContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void setSpanContext(java.lang.Throwable throwable, io.sentry.ISpan iSpan, java.lang.String string)` + void setSpanContext( + jni$_.JObject throwable, + jni$_.JObject iSpan, + jni$_.JString string, + ) { + final _$throwable = throwable.reference; + final _$iSpan = iSpan.reference; + final _$string = string.reference; + _setSpanContext(reference.pointer, _id_setSpanContext as jni$_.JMethodIDPtr, + _$throwable.pointer, _$iSpan.pointer, _$string.pointer) + .check(); + } + + static final _id_replaceOptions = _class.instanceMethodId( + r'replaceOptions', + r'(Lio/sentry/SentryOptions;)V', + ); + + static final _replaceOptions = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public void replaceOptions(io.sentry.SentryOptions sentryOptions)` + void replaceOptions( + jni$_.JObject sentryOptions, + ) { + final _$sentryOptions = sentryOptions.reference; + _replaceOptions(reference.pointer, _id_replaceOptions as jni$_.JMethodIDPtr, + _$sentryOptions.pointer) + .check(); + } +} + +final class $Scope$NullableType extends jni$_.JObjType { + @jni$_.internal + const $Scope$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope;'; + + @jni$_.internal + @core$_.override + Scope? fromReference(jni$_.JReference reference) => reference.isNull + ? null + : Scope.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => this; + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$NullableType) && + other is $Scope$NullableType; + } +} + +final class $Scope$Type extends jni$_.JObjType { + @jni$_.internal + const $Scope$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/Scope;'; + + @jni$_.internal + @core$_.override + Scope fromReference(jni$_.JReference reference) => Scope.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => const $Scope$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($Scope$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($Scope$Type) && other is $Scope$Type; + } +} + +/// from: `io.sentry.ScopeCallback` +class ScopeCallback extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + ScopeCallback.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = jni$_.JClass.forName(r'io/sentry/ScopeCallback'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $ScopeCallback$NullableType(); + static const type = $ScopeCallback$Type(); + static final _id_run = _class.instanceMethodId( + r'run', + r'(Lio/sentry/IScope;)V', + ); + + static final _run = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public abstract void run(io.sentry.IScope iScope)` + void run( + jni$_.JObject iScope, + ) { + final _$iScope = iScope.reference; + _run(reference.pointer, _id_run as jni$_.JMethodIDPtr, _$iScope.pointer) + .check(); + } + + /// Maps a specific port to the implemented interface. + static final core$_.Map _$impls = {}; + static jni$_.JObjectPtr _$invoke( + int port, + jni$_.JObjectPtr descriptor, + jni$_.JObjectPtr args, + ) { + return _$invokeMethod( + port, + jni$_.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final jni$_.Pointer< + jni$_.NativeFunction< + jni$_.JObjectPtr Function( + jni$_.Int64, jni$_.JObjectPtr, jni$_.JObjectPtr)>> + _$invokePointer = jni$_.Pointer.fromFunction(_$invoke); + + static jni$_.Pointer _$invokeMethod( + int $p, + jni$_.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == r'run(Lio/sentry/IScope;)V') { + _$impls[$p]!.run( + $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), + ); + return jni$_.nullptr; + } + } catch (e) { + return jni$_.ProtectedJniExtensions.newDartException(e); + } + return jni$_.nullptr; + } + + static void implementIn( + jni$_.JImplementer implementer, + $ScopeCallback $impl, + ) { + late final jni$_.RawReceivePort $p; + $p = jni$_.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = jni$_.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + jni$_.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'io.sentry.ScopeCallback', + $p, + _$invokePointer, + [ + if ($impl.run$async) r'run(Lio/sentry/IScope;)V', + ], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory ScopeCallback.implement( + $ScopeCallback $impl, + ) { + final $i = jni$_.JImplementer(); + implementIn($i, $impl); + return ScopeCallback.fromReference( + $i.implementReference(), + ); + } +} + +abstract base mixin class $ScopeCallback { + factory $ScopeCallback({ + required void Function(jni$_.JObject iScope) run, + bool run$async, + }) = _$ScopeCallback; + + void run(jni$_.JObject iScope); + bool get run$async => false; +} + +final class _$ScopeCallback with $ScopeCallback { + _$ScopeCallback({ + required void Function(jni$_.JObject iScope) run, + this.run$async = false, + }) : _run = run; + + final void Function(jni$_.JObject iScope) _run; + final bool run$async; + + void run(jni$_.JObject iScope) { + return _run(iScope); + } +} + +final class $ScopeCallback$NullableType extends jni$_.JObjType { + @jni$_.internal + const $ScopeCallback$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/ScopeCallback;'; + + @jni$_.internal + @core$_.override + ScopeCallback? fromReference(jni$_.JReference reference) => reference.isNull + ? null + : ScopeCallback.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => this; + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($ScopeCallback$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($ScopeCallback$NullableType) && + other is $ScopeCallback$NullableType; + } +} + +final class $ScopeCallback$Type extends jni$_.JObjType { + @jni$_.internal + const $ScopeCallback$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/ScopeCallback;'; + + @jni$_.internal + @core$_.override + ScopeCallback fromReference(jni$_.JReference reference) => + ScopeCallback.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $ScopeCallback$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($ScopeCallback$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($ScopeCallback$Type) && + other is $ScopeCallback$Type; + } +} + /// from: `io.sentry.protocol.User$Deserializer` class User$Deserializer extends jni$_.JObject { @jni$_.internal diff --git a/packages/flutter/lib/src/native/java/sentry_native_java.dart b/packages/flutter/lib/src/native/java/sentry_native_java.dart index 154ba60b26..a54fd21eca 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java.dart @@ -284,6 +284,41 @@ class SentryNativeJava extends SentryNativeChannel { } }); }); + + @override + void setContexts(String key, value) => tryCatchSync('setContexts', () { + native.Sentry.configureScope( + native.ScopeCallback.implement( + native.$ScopeCallback( + run: (iScope) { + using((arena) { + final jKey = key.toJString()..releasedBy(arena); + final jVal = _dartToJObject(value, arena); + + if (jVal == null) return; + + final scope = iScope.as(const native.$Scope$Type()) + ..releasedBy(arena); + scope.setContexts(jKey, jVal); + }); + }, + ), + ), + ); + }); + + @override + void removeContexts(String key) => tryCatchSync('removeContexts', () { + native.Sentry.configureScope( + native.ScopeCallback.implement(native.$ScopeCallback(run: (iScope) { + using((arena) { + final jKey = key.toJString()..releasedBy(arena); + final scope = iScope.as(const native.$Scope$Type()) + ..releasedBy(arena); + scope.removeContexts(jKey); + }); + }))); + }); } JObject? _dartToJObject(Object? value, Arena arena) => switch (value) { diff --git a/packages/flutter/lib/src/native/native_scope_observer.dart b/packages/flutter/lib/src/native/native_scope_observer.dart index 22a24cbb70..0c00262693 100644 --- a/packages/flutter/lib/src/native/native_scope_observer.dart +++ b/packages/flutter/lib/src/native/native_scope_observer.dart @@ -11,12 +11,12 @@ class NativeScopeObserver implements ScopeObserver { final SentryOptions _options; @override - Future setContexts(String key, value) async { + FutureOr setContexts(String key, value) { // ignore: invalid_use_of_internal_member if (Contexts.defaultFields.contains(key)) { try { final json = (value as dynamic).toJson(); - await _native.setContexts(key, json); + return _native.setContexts(key, json); } catch (_) { _options.log( SentryLevel.error, @@ -24,13 +24,13 @@ class NativeScopeObserver implements ScopeObserver { ); } } else { - await _native.setContexts(key, value); + return _native.setContexts(key, value); } } @override - Future removeContexts(String key) async { - await _native.removeContexts(key); + FutureOr removeContexts(String key) { + return _native.removeContexts(key); } @override diff --git a/packages/flutter/lib/src/native/sentry_native_channel.dart b/packages/flutter/lib/src/native/sentry_native_channel.dart index 59da70c1e3..681a7ee199 100644 --- a/packages/flutter/lib/src/native/sentry_native_channel.dart +++ b/packages/flutter/lib/src/native/sentry_native_channel.dart @@ -104,12 +104,12 @@ class SentryNativeChannel FutureOr captureEnvelope( Uint8List envelopeData, bool containsUnhandledException) { assert( - false, "captureEnvelope should not be used through method channels."); + false, 'captureEnvelope should not be used through method channels.'); } @override FutureOr captureStructuredEnvelope(SentryEnvelope envelope) { - throw UnsupportedError("Not supported on this platform"); + throw UnsupportedError('Not supported on this platform'); } @override @@ -123,29 +123,29 @@ class SentryNativeChannel @override FutureOr setUser(SentryUser? user) async { - assert(false, "setUser should not be used through method channels."); + assert(false, 'setUser should not be used through method channels.'); } @override FutureOr addBreadcrumb(Breadcrumb breadcrumb) async { - assert(false, "addBreadcrumb should not be used through method channels."); + assert(false, 'addBreadcrumb should not be used through method channels.'); } @override FutureOr clearBreadcrumbs() async { assert( - false, "clearBreadcrumbs should not be used through method channels."); + false, 'clearBreadcrumbs should not be used through method channels.'); } @override - Future setContexts(String key, dynamic value) => channel.invokeMethod( - 'setContexts', - {'key': key, 'value': normalize(value)}, - ); + FutureOr setContexts(String key, dynamic value) { + assert(false, 'setContexts should not be used through method channels.'); + } @override - Future removeContexts(String key) => - channel.invokeMethod('removeContexts', {'key': key}); + FutureOr removeContexts(String key) { + assert(false, 'removeContexts should not be used through method channels.'); + } @override Future setExtra(String key, dynamic value) => channel.invokeMethod( @@ -167,7 +167,7 @@ class SentryNativeChannel @override int? startProfiler(SentryId traceId) => - throw UnsupportedError("Not supported on this platform"); + throw UnsupportedError('Not supported on this platform'); @override Future discardProfiler(SentryId traceId) => @@ -185,7 +185,7 @@ class SentryNativeChannel @override FutureOr?> loadDebugImages(SentryStackTrace stackTrace) { assert( - false, "loadDebugImages should not be used through method channels."); + false, 'loadDebugImages should not be used through method channels.'); return null; } From ba423d7ff125068d27edf1701dd14a504e826a39 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 23 Oct 2025 17:18:06 +0200 Subject: [PATCH 02/10] Update scope --- packages/dart/lib/src/scope.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dart/lib/src/scope.dart b/packages/dart/lib/src/scope.dart index fef52b5d9f..d36bfafbcd 100644 --- a/packages/dart/lib/src/scope.dart +++ b/packages/dart/lib/src/scope.dart @@ -138,17 +138,17 @@ class Scope { } /// add an entry to the Scope's contexts - Future setContexts(String key, dynamic value) async { + FutureOr setContexts(String key, dynamic value) { _setContextsSync(key, value); - await _callScopeObservers( + return _callScopeObservers( (scopeObserver) async => await scopeObserver.setContexts(key, value)); } /// Removes a value from the Scope's contexts - Future removeContexts(String key) async { + FutureOr removeContexts(String key) { _contexts.remove(key); - await _callScopeObservers( + return _callScopeObservers( (scopeObserver) async => await scopeObserver.removeContexts(key)); } From 0fe5e7a413c51b99c7120c59f60f162310b62845 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 23 Oct 2025 17:21:44 +0200 Subject: [PATCH 03/10] Integration test --- .../integration_test/integration_test.dart | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/flutter/example/integration_test/integration_test.dart b/packages/flutter/example/integration_test/integration_test.dart index e7b833bf82..6667ec2e75 100644 --- a/packages/flutter/example/integration_test/integration_test.dart +++ b/packages/flutter/example/integration_test/integration_test.dart @@ -737,6 +737,57 @@ void main() { } }); + testWidgets('setContexts and removedContexts sync to native', (tester) async { + await restoreFlutterOnErrorAfter(() async { + await setupSentryAndApp(tester); + }); + + await Sentry.configureScope((scope) async { + scope.setContexts('key1', 'randomValue'); + scope.setContexts('key2', {'Key': 'Value'}); + scope.setContexts('key3', true); + scope.setContexts('key4', 12); + scope.setContexts('key5', 12.3); + }); + + var contexts = await SentryFlutter.native?.loadContexts(); + final values = contexts!['contexts']; + expect(values, isNotNull, reason: 'Contexts are null'); + + if (Platform.isIOS) { + expect(values['key1'], {'value': 'randomValue'}, reason: 'key1 mismatch'); + expect(values['key2'], {'Key': 'Value'}, reason: 'key2 mismatch'); + // bool values are mapped to num values of 1 or 0 during objc conversion + expect(values['key3'], {'value': 1}, reason: 'key3 mismatch'); + expect(values['key4'], {'value': 12}, reason: 'key4 mismatch'); + expect(values['key5'], {'value': 12.3}, reason: 'key5 mismatch'); + } else if (Platform.isAndroid) { + expect(values['key1'], 'randomValue', reason: 'key1 mismatch'); + expect(values['key2'], {'Key': 'Value'}, reason: 'key2 mismatch'); + expect(values['key3'], true, reason: 'key3 mismatch'); + expect(values['key4'], 12, reason: 'key4 mismatch'); + expect(values['key5'], 12.3, reason: 'key5 mismatch'); + } + + await Sentry.configureScope((scope) async { + scope.removeContexts('key1'); + scope.removeContexts('key2'); + scope.removeContexts('key3'); + scope.removeContexts('key4'); + scope.removeContexts('key5'); + }); + + contexts = await SentryFlutter.native?.loadContexts(); + final removedValues = contexts!['contexts']; + expect(removedValues, isNotNull, reason: 'Contexts are null'); + + expect(removedValues['key1'], isNull, reason: 'key1 should be removed'); + expect(removedValues['key2'], isNull, reason: 'key2 should be removed'); + expect(removedValues['key3'], isNull, reason: 'key3 should be removed'); + expect(removedValues['key4'], isNull, reason: 'key4 should be removed'); + expect(removedValues['key5'], isNull, reason: 'key5 should be removed'); + }); + group('e2e', () { var output = find.byKey(const Key('output')); late Fixture fixture; From 190423135b187e6b26a4a6b3a795bd7a561356b8 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 23 Oct 2025 17:25:11 +0200 Subject: [PATCH 04/10] Fix swift lint --- .../Sources/sentry_flutter/SentryFlutterPlugin.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift index 146a8dc1d2..91e3b16459 100644 --- a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift +++ b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -67,7 +67,6 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { ?? iso8601Formatter.date(from: iso8601String) // Parse date with low precision formatter for backward compatible } - // swiftlint:disable:next cyclomatic_complexity public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method as String { case "initNativeSdk": From 79db1a22356330844708618952f79713d28c6ce3 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 23 Oct 2025 17:25:52 +0200 Subject: [PATCH 05/10] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6644c099..b466aeb2fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Enhancements +- Refactor `setContexts` and `removeContexts` to use FFI/JNI ([#3312](https://github.com/getsentry/sentry-dart/pull/3312)) - Refactor `setUser` to use FFI/JNI ([#3295](https://github.com/getsentry/sentry-dart/pull/3295/)) - Refactor native breadcrumbs sync to use FFI/JNI ([#3293](https://github.com/getsentry/sentry-dart/pull/3293/)) - Refactor app hang and crash apis to use FFI/JNI ([#3289](https://github.com/getsentry/sentry-dart/pull/3289/)) From fb84a6864c25712c8134136045fa49d3e9c3d976 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Sat, 25 Oct 2025 17:48:45 +0200 Subject: [PATCH 06/10] Improve objc conversion --- .../integration_test/integration_test.dart | 11 +++++-- .../src/native/cocoa/sentry_native_cocoa.dart | 33 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/flutter/example/integration_test/integration_test.dart b/packages/flutter/example/integration_test/integration_test.dart index 6667ec2e75..8821da0f8e 100644 --- a/packages/flutter/example/integration_test/integration_test.dart +++ b/packages/flutter/example/integration_test/integration_test.dart @@ -744,7 +744,8 @@ void main() { await Sentry.configureScope((scope) async { scope.setContexts('key1', 'randomValue'); - scope.setContexts('key2', {'Key': 'Value'}); + scope.setContexts('key2', + {'String': 'Value', 'Bool': true, 'Int': 123, 'Double': 12.3}); scope.setContexts('key3', true); scope.setContexts('key4', 12); scope.setContexts('key5', 12.3); @@ -756,14 +757,18 @@ void main() { if (Platform.isIOS) { expect(values['key1'], {'value': 'randomValue'}, reason: 'key1 mismatch'); - expect(values['key2'], {'Key': 'Value'}, reason: 'key2 mismatch'); + expect(values['key2'], + {'String': 'Value', 'Bool': 1, 'Int': 123, 'Double': 12.3}, + reason: 'key2 mismatch'); // bool values are mapped to num values of 1 or 0 during objc conversion expect(values['key3'], {'value': 1}, reason: 'key3 mismatch'); expect(values['key4'], {'value': 12}, reason: 'key4 mismatch'); expect(values['key5'], {'value': 12.3}, reason: 'key5 mismatch'); } else if (Platform.isAndroid) { expect(values['key1'], 'randomValue', reason: 'key1 mismatch'); - expect(values['key2'], {'Key': 'Value'}, reason: 'key2 mismatch'); + expect(values['key2'], + {'String': 'Value', 'Bool': true, 'Int': 123, 'Double': 12.3}, + reason: 'key2 mismatch'); expect(values['key3'], true, reason: 'key3 mismatch'); expect(values['key4'], 12, reason: 'key4 mismatch'); expect(values['key5'], 12.3, reason: 'key5 mismatch'); diff --git a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart index f034c3df83..53ba33e52b 100644 --- a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart +++ b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart @@ -198,7 +198,7 @@ class SentryNativeCocoa extends SentryNativeChannel { tryCatchSync('addBreadcrumb', () { final nativeBreadcrumb = cocoa.PrivateSentrySDKOnly.breadcrumbWithDictionary( - _deepConvertMapNonNull(breadcrumb.toJson()).toNSDictionary()); + _dartToNSDictionary(breadcrumb.toJson())); cocoa.SentrySDK.addBreadcrumb(nativeBreadcrumb); }); @@ -229,8 +229,7 @@ class SentryNativeCocoa extends SentryNativeChannel { if (user == null) { cocoa.SentrySDK.setUser(null); } else { - final dictionary = - _deepConvertMapNonNull(user.toJson()).toNSDictionary(); + final dictionary = _dartToNSDictionary(user.toJson()); final cUser = cocoa.PrivateSentrySDKOnly.userWithDictionary(dictionary); cocoa.SentrySDK.setUser(cUser); @@ -244,13 +243,9 @@ class SentryNativeCocoa extends SentryNativeChannel { final normalizedValue = normalize(value); dictionary = switch (normalizedValue) { - Map m => _deepConvertMapNonNull(m).toNSDictionary(), - bool b => NSDictionary.fromEntries([ - MapEntry( - 'value'.toNSString(), b ? 1.toNSNumber() : 0.toNSNumber()) - ]), + Map m => _dartToNSDictionary(m), Object o => NSDictionary.fromEntries( - [MapEntry('value'.toNSString(), toObjCObject(o))]), + [MapEntry('value'.toNSString(), _dartToNSObject(o))]), _ => null }; @@ -273,6 +268,26 @@ class SentryNativeCocoa extends SentryNativeChannel { }); } +// The default conversion does not handle bool so we will add it ourselves +final ObjCObjectBase Function(Object) _defaultObjcConverter = (obj) { + return switch (obj) { + bool b => b ? 1.toNSNumber() : 0.toNSNumber(), + _ => toObjCObject(obj) + }; +}; + +NSDictionary _dartToNSDictionary(Map json) { + return _deepConvertMapNonNull(json) + .toNSDictionary(convertOther: _defaultObjcConverter); +} + +ObjCObjectBase _dartToNSObject(Object value) { + return switch (value) { + Map m => _dartToNSDictionary(m), + _ => toObjCObject(value, convertOther: _defaultObjcConverter) + }; +} + /// This map conversion is needed so we can use the toNSDictionary extension function /// provided by the objective_c package. Map _deepConvertMapNonNull(Map input) { From e03c03b92d3b07471e3ffc1fd7d40e17e5ebe6c7 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Sat, 25 Oct 2025 17:58:13 +0200 Subject: [PATCH 07/10] Fix tests --- .../test/sentry_native_channel_test.dart | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/flutter/test/sentry_native_channel_test.dart b/packages/flutter/test/sentry_native_channel_test.dart index 609a50479b..16ed15eab0 100644 --- a/packages/flutter/test/sentry_native_channel_test.dart +++ b/packages/flutter/test/sentry_native_channel_test.dart @@ -96,25 +96,27 @@ void main() { test('setContexts', () async { final value = {'object': Object()}; - final normalizedValue = normalize(value); - when(channel.invokeMethod('setContexts', { - 'key': 'fixture-key', - 'value': normalizedValue - })).thenAnswer((_) => Future.value()); + final matcher = _nativeUnavailableMatcher( + mockPlatform, + includeLookupSymbol: true, + includeFailedToLoadClassException: true, + ); - await sut.setContexts('fixture-key', value); + expect(() => sut.setContexts('fixture-key', value), matcher); - verify(channel.invokeMethod( - 'setContexts', {'key': 'fixture-key', 'value': normalizedValue})); + verifyZeroInteractions(channel); }); test('removeContexts', () async { - when(channel.invokeMethod('removeContexts', {'key': 'fixture-key'})) - .thenAnswer((_) => Future.value()); + final matcher = _nativeUnavailableMatcher( + mockPlatform, + includeLookupSymbol: true, + includeFailedToLoadClassException: true, + ); - await sut.removeContexts('fixture-key'); + expect(() => sut.removeContexts('fixture-key'), matcher); - verify(channel.invokeMethod('removeContexts', {'key': 'fixture-key'})); + verifyZeroInteractions(channel); }); test('setExtra', () async { From 6fcf3ed18ec37ec864ccccf3e1b33935fcf91b77 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Sat, 25 Oct 2025 18:07:52 +0200 Subject: [PATCH 08/10] Remove native channel from coverage --- .github/actions/flutter-test/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/flutter-test/action.yml b/.github/actions/flutter-test/action.yml index f06b5962ab..497f8a6f65 100644 --- a/.github/actions/flutter-test/action.yml +++ b/.github/actions/flutter-test/action.yml @@ -51,6 +51,7 @@ runs: # Remove native binding/bridge files from coverage. # These FFI/JNI bindings are currently not unit tested due to limitations of FFI/JNI mocking. dart run remove_from_coverage -f coverage/lcov.info -r 'binding.dart' + dart run remove_from_coverage -f coverage/lcov.info -r 'lib/src/native/sentry_native_channel.dart' dart run remove_from_coverage -f coverage/lcov.info -r 'lib/src/native/java/sentry_native_java.dart' dart run remove_from_coverage -f coverage/lcov.info -r 'lib/src/native/cocoa/sentry_native_cocoa.dart' fi From 8dcc1d06f31372604c451632ec1ce5826fb68a5b Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Sat, 25 Oct 2025 18:55:05 +0200 Subject: [PATCH 09/10] Refactor setTag and removeTag to FFI/JNI --- .../io/sentry/flutter/SentryFlutterPlugin.kt | 29 --------------- .../integration_test/integration_test.dart | 30 ++++++++++++++++ packages/flutter/ffi-cocoa.yaml | 2 ++ .../sentry_flutter/SentryFlutterPlugin.swift | 35 ------------------- .../flutter/lib/src/native/cocoa/binding.dart | 15 ++++++++ .../src/native/cocoa/sentry_native_cocoa.dart | 18 ++++++++++ .../src/native/java/sentry_native_java.dart | 17 +++++++++ .../lib/src/native/sentry_native_channel.dart | 10 +++--- .../test/sentry_native_channel_test.dart | 24 +++++++------ 9 files changed, 102 insertions(+), 78 deletions(-) diff --git a/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt b/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt index aad94df0e8..522bd0e62f 100644 --- a/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt +++ b/packages/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt @@ -63,8 +63,6 @@ class SentryFlutterPlugin : "closeNativeSdk" -> closeNativeSdk(result) "setExtra" -> setExtra(call.argument("key"), call.argument("value"), result) "removeExtra" -> removeExtra(call.argument("key"), result) - "setTag" -> setTag(call.argument("key"), call.argument("value"), result) - "removeTag" -> removeTag(call.argument("key"), result) "setReplayConfig" -> setReplayConfig(call, result) "captureReplay" -> captureReplay(result) else -> result.notImplemented() @@ -166,33 +164,6 @@ class SentryFlutterPlugin : result.success("") } - private fun setTag( - key: String?, - value: String?, - result: Result, - ) { - if (key == null || value == null) { - result.success("") - return - } - Sentry.setTag(key, value) - - result.success("") - } - - private fun removeTag( - key: String?, - result: Result, - ) { - if (key == null) { - result.success("") - return - } - Sentry.removeTag(key) - - result.success("") - } - private fun closeNativeSdk(result: Result) { ScopesAdapter.getInstance().close() diff --git a/packages/flutter/example/integration_test/integration_test.dart b/packages/flutter/example/integration_test/integration_test.dart index 8821da0f8e..104e966027 100644 --- a/packages/flutter/example/integration_test/integration_test.dart +++ b/packages/flutter/example/integration_test/integration_test.dart @@ -793,6 +793,36 @@ void main() { expect(removedValues['key5'], isNull, reason: 'key5 should be removed'); }); + testWidgets('setTag and removeTag sync to native', (tester) async { + await restoreFlutterOnErrorAfter(() async { + await setupSentryAndApp(tester); + }); + + await Sentry.configureScope((scope) async { + scope.setTag('key1', 'randomValue'); + scope.setTag('key2', '12'); + }); + + var contexts = await SentryFlutter.native?.loadContexts(); + final tags = contexts!['tags']; + expect(tags, isNotNull, reason: 'Tags are null'); + + expect(tags['key1'], 'randomValue', reason: 'key1 mismatch'); + expect(tags['key2'], '12', reason: 'key2 mismatch'); + + await Sentry.configureScope((scope) async { + scope.removeTag('key1'); + scope.removeTag('key2'); + }); + + contexts = await SentryFlutter.native?.loadContexts(); + if (Platform.isIOS) { + expect(contexts!['tags'], isNull, reason: 'Tags are not null'); + } else if (Platform.isAndroid) { + expect(contexts!['tags'], isEmpty, reason: 'Tags are not empty'); + } + }); + group('e2e', () { var output = find.byKey(const Key('output')); late Fixture fixture; diff --git a/packages/flutter/ffi-cocoa.yaml b/packages/flutter/ffi-cocoa.yaml index 45110532e7..0ce1d9751c 100644 --- a/packages/flutter/ffi-cocoa.yaml +++ b/packages/flutter/ffi-cocoa.yaml @@ -40,6 +40,8 @@ objc-interfaces: - 'clearBreadcrumbs' - 'setContextValue:forKey:' - 'removeContextForKey:' + - 'setTagValue:forKey:' + - 'removeTagForKey:' preamble: | // ignore_for_file: type=lint, unused_element diff --git a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift index 91e3b16459..f9f856a69d 100644 --- a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift +++ b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -86,17 +86,6 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { let key = arguments?["key"] as? String removeExtra(key: key, result: result) - case "setTag": - let arguments = call.arguments as? [String: Any?] - let key = arguments?["key"] as? String - let value = arguments?["value"] as? String - setTag(key: key, value: value, result: result) - - case "removeTag": - let arguments = call.arguments as? [String: Any?] - let key = arguments?["key"] as? String - removeTag(key: key, result: result) - #if !os(tvOS) && !os(watchOS) case "discardProfiler": discardProfiler(call, result) @@ -278,30 +267,6 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { } } - private func setTag(key: String?, value: String?, result: @escaping FlutterResult) { - guard let key = key, let value = value else { - result("") - return - } - SentrySDK.configureScope { scope in - scope.setTag(value: value, key: key) - - result("") - } - } - - private func removeTag(key: String?, result: @escaping FlutterResult) { - guard let key = key else { - result("") - return - } - SentrySDK.configureScope { scope in - scope.removeTag(key: key) - - result("") - } - } - private func collectProfile(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { guard let arguments = call.arguments as? [String: Any], let traceId = arguments["traceId"] as? String else { diff --git a/packages/flutter/lib/src/native/cocoa/binding.dart b/packages/flutter/lib/src/native/cocoa/binding.dart index 3119e4c4c9..8db80acafa 100644 --- a/packages/flutter/lib/src/native/cocoa/binding.dart +++ b/packages/flutter/lib/src/native/cocoa/binding.dart @@ -1148,6 +1148,8 @@ interface class SentrySerializable extends objc.ObjCProtocolBase : this._(other, retain: retain, release: release); } +late final _sel_setTagValue_forKey_ = objc.registerName("setTagValue:forKey:"); +late final _sel_removeTagForKey_ = objc.registerName("removeTagForKey:"); late final _sel_clearBreadcrumbs = objc.registerName("clearBreadcrumbs"); final _objc_msgSend_1pl9qdv = objc.msgSendPointer .cast< @@ -1183,6 +1185,19 @@ class SentryScope extends objc.NSObject implements SentrySerializable { obj.ref.pointer, _sel_isKindOfClass_, _class_SentryScope); } + /// Set a global tag. Tags are searchable key/value string pairs attached to + /// every event. + void setTagValue(objc.NSString value, {required objc.NSString forKey}) { + _objc_msgSend_pfv6jd(this.ref.pointer, _sel_setTagValue_forKey_, + value.ref.pointer, forKey.ref.pointer); + } + + /// Remove the tag for the specified key. + void removeTagForKey(objc.NSString key) { + _objc_msgSend_xtuoz7( + this.ref.pointer, _sel_removeTagForKey_, key.ref.pointer); + } + /// Clears all breadcrumbs in the scope void clearBreadcrumbs() { _objc_msgSend_1pl9qdv(this.ref.pointer, _sel_clearBreadcrumbs); diff --git a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart index 53ba33e52b..5bfd0ef131 100644 --- a/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart +++ b/packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart @@ -266,6 +266,24 @@ class SentryNativeCocoa extends SentryNativeChannel { scope.removeContextForKey(key.toNSString()); })); }); + + @override + void setTag(String key, String value) => tryCatchSync('setTag', () { + cocoa.SentrySDK.configureScope( + cocoa.ObjCBlock_ffiVoid_SentryScope.fromFunction( + (cocoa.SentryScope scope) { + scope.setTagValue(value.toNSString(), forKey: key.toNSString()); + })); + }); + + @override + void removeTag(String key) => tryCatchSync('removeTag', () { + cocoa.SentrySDK.configureScope( + cocoa.ObjCBlock_ffiVoid_SentryScope.fromFunction( + (cocoa.SentryScope scope) { + scope.removeTagForKey(key.toNSString()); + })); + }); } // The default conversion does not handle bool so we will add it ourselves diff --git a/packages/flutter/lib/src/native/java/sentry_native_java.dart b/packages/flutter/lib/src/native/java/sentry_native_java.dart index a54fd21eca..ac5142a73b 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java.dart @@ -319,6 +319,23 @@ class SentryNativeJava extends SentryNativeChannel { }); }))); }); + + @override + void setTag(String key, String value) => tryCatchSync('setTag', () { + using((arena) { + final jKey = key.toJString()..releasedBy(arena); + final jVal = value.toJString()..releasedBy(arena); + native.Sentry.setTag(jKey, jVal); + }); + }); + + @override + void removeTag(String key) => tryCatchSync('removeTag', () { + using((arena) { + final jKey = key.toJString()..releasedBy(arena); + native.Sentry.removeTag(jKey); + }); + }); } JObject? _dartToJObject(Object? value, Arena arena) => switch (value) { diff --git a/packages/flutter/lib/src/native/sentry_native_channel.dart b/packages/flutter/lib/src/native/sentry_native_channel.dart index 681a7ee199..3c4754c07e 100644 --- a/packages/flutter/lib/src/native/sentry_native_channel.dart +++ b/packages/flutter/lib/src/native/sentry_native_channel.dart @@ -158,12 +158,14 @@ class SentryNativeChannel channel.invokeMethod('removeExtra', {'key': key}); @override - Future setTag(String key, String value) => - channel.invokeMethod('setTag', {'key': key, 'value': value}); + FutureOr setTag(String key, String value) { + assert(false, 'setTag should not be used through method channels.'); + } @override - Future removeTag(String key) => - channel.invokeMethod('removeTag', {'key': key}); + FutureOr removeTag(String key) { + assert(false, 'removeTag should not be used through method channels.'); + } @override int? startProfiler(SentryId traceId) => diff --git a/packages/flutter/test/sentry_native_channel_test.dart b/packages/flutter/test/sentry_native_channel_test.dart index 16ed15eab0..d8f7f5e47a 100644 --- a/packages/flutter/test/sentry_native_channel_test.dart +++ b/packages/flutter/test/sentry_native_channel_test.dart @@ -142,23 +142,27 @@ void main() { }); test('setTag', () async { - when(channel.invokeMethod( - 'setTag', {'key': 'fixture-key', 'value': 'fixture-value'})) - .thenAnswer((_) => Future.value()); + final matcher = _nativeUnavailableMatcher( + mockPlatform, + includeLookupSymbol: true, + includeFailedToLoadClassException: true, + ); - await sut.setTag('fixture-key', 'fixture-value'); + expect(() => sut.setTag('fixture-key', 'fixture-value'), matcher); - verify(channel.invokeMethod( - 'setTag', {'key': 'fixture-key', 'value': 'fixture-value'})); + verifyZeroInteractions(channel); }); test('removeTag', () async { - when(channel.invokeMethod('removeTag', {'key': 'fixture-key'})) - .thenAnswer((_) => Future.value()); + final matcher = _nativeUnavailableMatcher( + mockPlatform, + includeLookupSymbol: true, + includeFailedToLoadClassException: true, + ); - await sut.removeTag('fixture-key'); + expect(() => sut.removeTag('fixture-key'), matcher); - verify(channel.invokeMethod('removeTag', {'key': 'fixture-key'})); + verifyZeroInteractions(channel); }); test('startProfiler', () { From 26a35ec0e9af651e0c18d40a7603c009c85e70ae Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 30 Oct 2025 09:10:10 +0000 Subject: [PATCH 10/10] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b782456bb0..c38e37bedd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Enhancements +- Refactor `setTag` and `removeTag` to use FFI/JNI ([#3313](https://github.com/getsentry/sentry-dart/pull/3313)) - Refactor `setContexts` and `removeContexts` to use FFI/JNI ([#3312](https://github.com/getsentry/sentry-dart/pull/3312)) - Refactor `setUser` to use FFI/JNI ([#3295](https://github.com/getsentry/sentry-dart/pull/3295/)) - Refactor native breadcrumbs sync to use FFI/JNI ([#3293](https://github.com/getsentry/sentry-dart/pull/3293/))