From 3f47ea382fb4bd725620e52437326a85898c585a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:40:56 +0100 Subject: [PATCH 01/62] build(deps): bump actions/cache from 4 to 5 (#3423) Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/metrics.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml index 752ea55b6b..bd23cd29a6 100644 --- a/.github/workflows/metrics.yml +++ b/.github/workflows/metrics.yml @@ -61,7 +61,7 @@ jobs: - run: ./metrics/prepare.sh - - uses: actions/cache@v4 + - uses: actions/cache@v5 id: app-plain-cache with: path: ${{ matrix.appPlain }} From 695a030d51d6682d33622f5d9b0b628019ec39c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:41:21 +0100 Subject: [PATCH 02/62] build(deps): bump actions/upload-artifact from 5 to 6 (#3399) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/flutter-symbols.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter-symbols.yml b/.github/workflows/flutter-symbols.yml index fd7f10871d..4b176f92da 100644 --- a/.github/workflows/flutter-symbols.yml +++ b/.github/workflows/flutter-symbols.yml @@ -52,7 +52,7 @@ jobs: FLUTTER_VERSION: ${{ inputs.flutter_version || '3.*.*' }} - name: Upload updated status cache of processed files - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 if: always() with: name: flutter-symbol-collector-database From 51520fc6f93f50b59e72187a17d552e2a5aeb93a Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 5 Jan 2026 15:20:06 +0100 Subject: [PATCH 03/62] enh(internal): internal logging api (#3425) * feat(logging): introduce SentryDebugLogger for enhanced diagnostic logging This commit adds a new `SentryDebugLogger` class to provide a lightweight, isolate-compatible logging solution for the Sentry SDK. The logger supports various log levels and can be configured for each isolate. Additionally, it integrates with `SentryOptions` to enable logging based on the debug flag and diagnostic level. The existing `IsolateLogger` has been removed in favor of this new implementation, streamlining the logging process across the SDK. - Added `SentryDebugLogger` for structured logging. - Updated `SentryOptions` to configure the logger based on debug settings. - Replaced instances of `IsolateLogger` with `SentryDebugLogger` in relevant files. - Added unit tests for the new logger functionality. * refactor(sentry): remove debug logger warning from Sentry initialization This commit removes a debug logger warning message from the Sentry class during initialization. The change helps to clean up the logging output and streamline the initialization process without affecting functionality. * docs(debug_logger): update example usage and clarify instance requirements This commit updates the documentation for the `SentryDebugLogger` to reflect the correct variable name in the example and adds a note emphasizing that each package should have at least one top-level instance of the logger. This enhances clarity for users implementing the logger in their applications. * refactor(sentry): remove unused debug logger import and enhance debug logger documentation This commit removes the unused import of the debug logger from the Sentry class and adds an internal annotation to the `SentryDebugLogger` in the debug logger file. Additionally, a comment is added in the isolate worker to suppress a lint warning related to the internal member usage, improving code clarity and maintainability. * refactor(sentry): remove unused debug logger import from sentry_options.dart This commit removes the unused import of the debug logger from the `sentry_options.dart` file, contributing to cleaner code and improved maintainability. * docs(debug_logger): correct example usage in documentation This commit updates the example usage in the `SentryDebugLogger` documentation to reflect the correct variable name, enhancing clarity for users implementing the logger in their applications. * Update * refactor(debug_logger): remove unused category parameter from logging methods This commit simplifies the `SentryDebugLogger` class by removing the unused `category` parameter from the `debug`, `info`, `warning`, `error`, and `fatal` logging methods. This change enhances code clarity and reduces unnecessary complexity in the logging interface. * refactor(debug_logger_test): remove test for category logging This commit removes the test case that checks logging with a category parameter from the `debug_logger_test.dart` file. This change aligns with the recent refactor of the `SentryDebugLogger` class, which eliminated the unused category parameter, thereby enhancing the clarity and relevance of the test suite. * refactor(android_replay_handler): enhance debug logging with context This commit updates the logging statements in the `_AndroidReplayHandler` class to include the debug name from the configuration. This change improves the clarity of log messages by providing context for unexpected messages and payload types, aiding in debugging and monitoring efforts. * refactor(debug_logger_test): enhance test coverage and improve naming conventions This commit refactors the `debug_logger_test.dart` file by renaming test groups for clarity and adding new tests to verify the behavior of `SentryOptions.debug` and `SentryOptions.diagnosticLevel`. The changes improve the organization and comprehensiveness of the test suite, ensuring better validation of the `SentryDebugLogger` configuration and logging functionality. * refactor(sentry_options): improve debug logger configuration and diagnostic level handling This commit refactors the `SentryOptions` class to enhance the configuration of the debug logger. The `diagnosticLevel` setter now updates the logger's minimum level dynamically, ensuring that changes to the diagnostic level are reflected immediately. Additionally, the debug logger configuration is encapsulated in a private method for better organization and clarity. * refactor(logging): replace SentryDebugLogger with SentryInternalLogger and enhance logging functionality This commit refactors the logging mechanism by replacing the `SentryDebugLogger` with the new `SentryInternalLogger` across the codebase. The `SentryInternalLogger` provides improved logging capabilities, including compile-time constants for release, profile, and debug modes, ensuring better tree-shaking and performance. Additionally, the associated tests have been updated to validate the new logger's behavior, enhancing overall logging clarity and maintainability. * refactor(logging): remove SentryDebugLogger and its import from the codebase This commit removes the `SentryDebugLogger` class and its associated import from `sentry_options.dart`, streamlining the logging functionality in the Sentry SDK. This change is part of the ongoing effort to enhance the logging mechanism by transitioning to the `SentryInternalLogger`, which offers improved capabilities and performance. * refactor(sentry_options): update logger configuration methods to use SentryInternalLogger This commit modifies the `SentryOptions` class to replace calls to the deprecated `_configureDebugLogger` method with `_configureInternalLogger`. This change aligns with the recent transition to the `SentryInternalLogger`, ensuring consistent logging configuration and improving overall code clarity. * refactor(logging): rename debugLogger to internalLogger for consistency This commit renames the `debugLogger` to `internalLogger` across the codebase, including tests and various components. This change aligns with the recent transition to the `SentryInternalLogger`, ensuring consistent naming and improving clarity in the logging functionality. * refactor(logging): remove debugLogger test and update logging references to internalLogger This commit removes the test for the `debugLogger` constant in `internal_logger_test.dart` and updates references from `debugLogger` to `internalLogger` in the `_AndroidEnvelopeHandler` and `_AndroidReplayHandler` classes. These changes ensure consistency in the logging implementation and align with the recent transition to the `SentryInternalLogger`. * refactor(logging): move _defaultLogOutput method to SentryInternalLogger This commit relocates the `_defaultLogOutput` method into the `SentryInternalLogger` class, enhancing the organization of the logging functionality. This change improves code clarity and aligns with the ongoing refactor to streamline the logging mechanism within the Sentry SDK. * refactor(logging): improve error logging format in isolate_worker This commit enhances the error logging format in the `isolate_worker.dart` file by improving the readability of the log statement. The changes ensure that the error and stack trace are clearly separated, contributing to better debugging and monitoring of isolate message handling failures. --- packages/dart/lib/sentry.dart | 2 + packages/dart/lib/src/runtime_checker.dart | 44 ++- packages/dart/lib/src/sentry_options.dart | 15 +- .../dart/lib/src/utils/internal_logger.dart | 156 ++++++++ .../dart/test/utils/internal_logger_test.dart | 339 ++++++++++++++++++ .../lib/src/isolate/isolate_logger.dart | 81 ----- .../lib/src/isolate/isolate_worker.dart | 20 +- .../native/java/android_envelope_sender.dart | 13 +- .../native/java/android_replay_recorder.dart | 14 +- .../lib/src/utils/internal_logger.dart | 6 + .../test/isolate/isolate_logger_test.dart | 70 ---- 11 files changed, 573 insertions(+), 187 deletions(-) create mode 100644 packages/dart/lib/src/utils/internal_logger.dart create mode 100644 packages/dart/test/utils/internal_logger_test.dart delete mode 100644 packages/flutter/lib/src/isolate/isolate_logger.dart create mode 100644 packages/flutter/lib/src/utils/internal_logger.dart delete mode 100644 packages/flutter/test/isolate/isolate_logger_test.dart diff --git a/packages/dart/lib/sentry.dart b/packages/dart/lib/sentry.dart index bb349a6a3c..8d01a3181c 100644 --- a/packages/dart/lib/sentry.dart +++ b/packages/dart/lib/sentry.dart @@ -61,3 +61,5 @@ export 'src/utils/url_details.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/breadcrumb_log_level.dart'; export 'src/sentry_logger.dart'; +// ignore: invalid_export_of_internal_element +export 'src/utils/internal_logger.dart' show SentryInternalLogger; diff --git a/packages/dart/lib/src/runtime_checker.dart b/packages/dart/lib/src/runtime_checker.dart index d458448b69..aac13ae4d5 100644 --- a/packages/dart/lib/src/runtime_checker.dart +++ b/packages/dart/lib/src/runtime_checker.dart @@ -9,20 +9,40 @@ class RuntimeChecker { bool? isRootZone, }) : isRootZone = isRootZone ?? Zone.current == Zone.root; - /// Check if running in release/production environment - bool isReleaseMode() { - return const bool.fromEnvironment('dart.vm.product', defaultValue: false); - } + /// Whether running in release/production environment as a compile-time constant for guaranteed tree-shaking. + /// + /// If the code needs to be testable, use [isReleaseMode] instead. + static const bool kReleaseMode = + bool.fromEnvironment('dart.vm.product', defaultValue: false); - /// Check if running in debug environment - bool isDebugMode() { - return !isReleaseMode() && !isProfileMode(); - } + /// Whether running in profile environment as a compile-time constant for guaranteed tree-shaking. + /// + /// If the code needs to be testable, use [isProfileMode] instead. + static const bool kProfileMode = + bool.fromEnvironment('dart.vm.profile', defaultValue: false); - /// Check if running in profile environment - bool isProfileMode() { - return const bool.fromEnvironment('dart.vm.profile', defaultValue: false); - } + /// Whether running in debug environment as a compile-time constant for guaranteed tree-shaking. + /// + /// If the code needs to be testable, use [isDebugMode] instead. + static const bool kDebugMode = !kReleaseMode && !kProfileMode; + + /// Whether running in release/production environment. + /// + /// Code paths using this method are not guaranteed to be tree-shaken in release builds. + /// If tree-shaking needs to be guaranteed, use [RuntimeChecker.kReleaseMode] instead. + bool isReleaseMode() => kReleaseMode; + + /// Whether running in debug environment. + /// + /// Code paths using this method are not guaranteed to be tree-shaken in non-debug builds. + /// If tree-shaking needs to be guaranteed, use [RuntimeChecker.kDebugMode] instead. + bool isDebugMode() => kDebugMode; + + /// Whether running in profile environment. + /// + /// Code paths using this method are not guaranteed to be tree-shaken in profile builds. + /// If tree-shaking needs to be guaranteed, use [RuntimeChecker.kProfileMode] instead. + bool isProfileMode() => kProfileMode; /// Check if the Dart code is obfuscated. bool isAppObfuscated() { diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index ba92e6df89..9cb8b881fa 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -162,6 +162,7 @@ class SentryOptions { set debug(bool newValue) { _debug = newValue; + _configureInternalLogger(); if (_debug == true && (log == noOpLog || diagnosticLog?.logger == noOpLog)) { log = debugLog; @@ -175,7 +176,19 @@ class SentryOptions { bool _debug = false; /// minimum LogLevel to be used if debug is enabled - SentryLevel diagnosticLevel = _defaultDiagnosticLevel; + SentryLevel get diagnosticLevel => _diagnosticLevel; + + set diagnosticLevel(SentryLevel newValue) { + _diagnosticLevel = newValue; + _configureInternalLogger(); + } + + SentryLevel _diagnosticLevel = _defaultDiagnosticLevel; + + void _configureInternalLogger() { + SentryInternalLogger.configure( + isEnabled: _debug, minLevel: _diagnosticLevel); + } /// Sentry client name used for the HTTP authHeader and userAgent eg /// sentry.{language}.{platform}/{version} eg sentry.java.android/2.0.0 would be a valid case diff --git a/packages/dart/lib/src/utils/internal_logger.dart b/packages/dart/lib/src/utils/internal_logger.dart new file mode 100644 index 0000000000..3f8c43a06d --- /dev/null +++ b/packages/dart/lib/src/utils/internal_logger.dart @@ -0,0 +1,156 @@ +import 'dart:developer' as dev; + +import 'package:meta/meta.dart'; + +import '../../sentry.dart'; + +typedef LogOutputFunction = void Function({ + required String name, + required SentryLevel level, + required String message, + Object? error, + StackTrace? stackTrace, +}); + +/// Lightweight isolate compatible diagnostic logger for the Sentry SDK. +/// +/// Logger naming convention: +/// - `sentry_dart` – core dart package +/// - `sentry_flutter` – flutter package +/// - `sentry_` – integration packages (dio, hive, etc.) +/// +/// Each package should have one top-level logger instance. +/// +/// All log methods accept [Object] for the message parameter. +/// If the message is a [Function], it will be lazily evaluated. +/// Non-string values are converted via `toString()`. +/// +/// Example: +/// ```dart +/// const logger = SentryInternalLogger('sentry_flutter'); +/// +/// logger.warning('Simple message'); +/// logger.debug(() => 'Expensive: ${computeDebugInfo()}'); // Lazy evaluation +/// ``` +@internal +class SentryInternalLogger { + final String _name; + + const SentryInternalLogger(this._name); + + static bool _isEnabled = false; + static SentryLevel _minLevel = SentryLevel.warning; + static LogOutputFunction _logOutput = _defaultLogOutput; + + @visibleForTesting + static bool get isEnabled => _isEnabled; + + @visibleForTesting + static SentryLevel get minLevel => _minLevel; + + /// Configure logging for the current isolate. + /// + /// This needs to be called for each new spawned isolate before logging. + static void configure({ + required bool isEnabled, + SentryLevel minLevel = SentryLevel.warning, + LogOutputFunction? logOutput, + }) { + _isEnabled = isEnabled; + _minLevel = minLevel; + if (logOutput != null) { + _logOutput = logOutput; + } + } + + static void _defaultLogOutput({ + required String name, + required SentryLevel level, + required String message, + Object? error, + StackTrace? stackTrace, + }) { + dev.log( + '[${level.name}] $message', + name: name, + level: level.toDartLogLevel(), + error: error, + stackTrace: stackTrace, + time: DateTime.now(), + ); + } + + static bool _isLoggable(SentryLevel level) { + return _isEnabled && level.ordinal >= _minLevel.ordinal; + } + + void debug( + Object message, { + Object? error, + StackTrace? stackTrace, + }) => + _log(SentryLevel.debug, message, error: error, stackTrace: stackTrace); + + void info( + Object message, { + Object? error, + StackTrace? stackTrace, + }) => + _log(SentryLevel.info, message, error: error, stackTrace: stackTrace); + + void warning( + Object message, { + Object? error, + StackTrace? stackTrace, + }) => + _log(SentryLevel.warning, message, error: error, stackTrace: stackTrace); + + void error( + Object message, { + Object? error, + StackTrace? stackTrace, + }) => + _log(SentryLevel.error, message, error: error, stackTrace: stackTrace); + + void fatal( + Object message, { + Object? error, + StackTrace? stackTrace, + }) => + _log(SentryLevel.fatal, message, error: error, stackTrace: stackTrace); + + @pragma('vm:prefer-inline') + void _log( + SentryLevel level, + Object message, { + Object? error, + StackTrace? stackTrace, + }) { + // Guarantee tree-shaking with const kDebugMode + if (!RuntimeChecker.kDebugMode) return; + if (!_isLoggable(level)) return; + + if (message is Function) { + message = (message as Object Function())(); + } + + String finalMessage; + if (message is String) { + finalMessage = message; + } else { + finalMessage = message.toString(); + } + + _logOutput( + name: _name, + level: level, + message: finalMessage, + error: error, + stackTrace: stackTrace, + ); + } +} + +/// Logger for the Sentry Dart SDK. +@internal +const internalLogger = SentryInternalLogger('sentry_dart'); diff --git a/packages/dart/test/utils/internal_logger_test.dart b/packages/dart/test/utils/internal_logger_test.dart new file mode 100644 index 0000000000..4724c4e8eb --- /dev/null +++ b/packages/dart/test/utils/internal_logger_test.dart @@ -0,0 +1,339 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/utils/internal_logger.dart'; +import 'package:test/test.dart'; + +import '../test_utils.dart'; + +void main() { + group(SentryInternalLogger, () { + late List<_CapturedLog> logs; + + LogOutputFunction captureLogOutput() { + return ({ + required String name, + required SentryLevel level, + required String message, + Object? error, + StackTrace? stackTrace, + }) { + logs.add(_CapturedLog( + name: name, + level: level, + message: message, + error: error, + stackTrace: stackTrace, + )); + }; + } + + setUp(() { + logs = []; + }); + + tearDown(() { + SentryInternalLogger.configure(isEnabled: false); + }); + + group('configuration', () { + test('enables logging when isEnabled is true', () { + SentryInternalLogger.configure(isEnabled: true); + + expect(SentryInternalLogger.isEnabled, isTrue); + }); + + test('disables logging when isEnabled is false', () { + SentryInternalLogger.configure(isEnabled: false); + + expect(SentryInternalLogger.isEnabled, isFalse); + }); + + test('sets minimum level', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.error, + ); + + expect(SentryInternalLogger.isEnabled, isTrue); + expect(SentryInternalLogger.minLevel, equals(SentryLevel.error)); + }); + + test('defaults minLevel to warning', () { + SentryInternalLogger.configure(isEnabled: true); + + expect(SentryInternalLogger.minLevel, equals(SentryLevel.warning)); + }); + + test('SentryOptions.debug enables logger', () { + final options = defaultTestOptions(); + + expect(options.debug, isFalse); + options.debug = true; + + expect(SentryInternalLogger.isEnabled, isTrue); + }); + + test('SentryOptions.diagnosticLevel sets minLevel when set before debug', + () { + final options = defaultTestOptions(); + + options.diagnosticLevel = SentryLevel.error; + options.debug = true; + + expect(SentryInternalLogger.isEnabled, isTrue); + expect(SentryInternalLogger.minLevel, equals(SentryLevel.error)); + }); + + test( + 'SentryOptions.diagnosticLevel updates minLevel when set after debug', + () { + final options = defaultTestOptions(); + + options.debug = true; + expect(SentryInternalLogger.minLevel, equals(SentryLevel.warning)); + + options.diagnosticLevel = SentryLevel.error; + + expect(SentryInternalLogger.isEnabled, isTrue); + expect(SentryInternalLogger.minLevel, equals(SentryLevel.error)); + }); + }); + + group('logging when enabled', () { + setUp(() { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.debug, + logOutput: captureLogOutput(), + ); + }); + + test('debug logs message with correct level', () { + internalLogger.debug('debug message'); + + expect(logs, hasLength(1)); + expect(logs.first.level, SentryLevel.debug); + expect(logs.first.message, 'debug message'); + expect(logs.first.name, 'sentry_dart'); + }); + + test('info logs message with correct level', () { + internalLogger.info('info message'); + + expect(logs, hasLength(1)); + expect(logs.first.level, SentryLevel.info); + expect(logs.first.message, 'info message'); + }); + + test('warning logs message with correct level', () { + internalLogger.warning('warning message'); + + expect(logs, hasLength(1)); + expect(logs.first.level, SentryLevel.warning); + expect(logs.first.message, 'warning message'); + }); + + test('error logs message with correct level', () { + internalLogger.error('error message'); + + expect(logs, hasLength(1)); + expect(logs.first.level, SentryLevel.error); + expect(logs.first.message, 'error message'); + }); + + test('fatal logs message with correct level', () { + internalLogger.fatal('fatal message'); + + expect(logs, hasLength(1)); + expect(logs.first.level, SentryLevel.fatal); + expect(logs.first.message, 'fatal message'); + }); + + test('includes error object in log entry', () { + final exception = Exception('test exception'); + + internalLogger.error('error occurred', error: exception); + + expect(logs, hasLength(1)); + expect(logs.first.error, exception); + }); + + test('includes stackTrace in log entry', () { + final stackTrace = StackTrace.current; + + internalLogger.error('error occurred', stackTrace: stackTrace); + + expect(logs, hasLength(1)); + expect(logs.first.stackTrace, stackTrace); + }); + }); + + group('logger instances', () { + test('logs with custom logger name', () { + const customLogger = SentryInternalLogger('sentry_flutter'); + SentryInternalLogger.configure( + isEnabled: true, + logOutput: captureLogOutput(), + ); + + customLogger.warning('test from flutter logger'); + + expect(logs, hasLength(1)); + expect(logs.first.name, 'sentry_flutter'); + }); + }); + + group('lazy evaluation', () { + test('does not evaluate function when logging is disabled', () { + SentryInternalLogger.configure(isEnabled: false); + var wasCalled = false; + + internalLogger.debug(() { + wasCalled = true; + return 'expensive message'; + }); + + expect(wasCalled, isFalse); + }); + + test('evaluates function when logging is enabled', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.debug, + ); + var wasCalled = false; + + internalLogger.debug(() { + wasCalled = true; + return 'expensive message'; + }); + + expect(wasCalled, isTrue); + }); + + test('does not evaluate function when level is below minLevel', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.warning, + ); + var wasCalled = false; + + internalLogger.debug(() { + wasCalled = true; + return 'debug message'; + }); + + expect(wasCalled, isFalse); + }); + }); + + group('level filtering', () { + test('logs message at minLevel', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.warning, + ); + var wasCalled = false; + + internalLogger.warning(() { + wasCalled = true; + return 'warning message'; + }); + + expect(wasCalled, isTrue); + }); + + test('logs message above minLevel', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.warning, + ); + var wasCalled = false; + + internalLogger.error(() { + wasCalled = true; + return 'error message'; + }); + + expect(wasCalled, isTrue); + }); + + test('does not log message below minLevel', () { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.error, + ); + var wasCalled = false; + + internalLogger.warning(() { + wasCalled = true; + return 'warning message'; + }); + + expect(wasCalled, isFalse); + }); + }); + + group('message conversion', () { + setUp(() { + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.debug, + logOutput: captureLogOutput(), + ); + }); + + test('converts int to string', () { + internalLogger.info(42); + + expect(logs, hasLength(1)); + expect(logs.first.message, '42'); + }); + + test('converts custom object using toString', () { + internalLogger.info(_TestMessage('custom')); + + expect(logs, hasLength(1)); + expect(logs.first.message, 'TestMessage: custom'); + }); + + test('converts list to string', () { + internalLogger.info([1, 2, 3]); + + expect(logs, hasLength(1)); + expect(logs.first.message, '[1, 2, 3]'); + }); + + test('evaluates function and converts result', () { + internalLogger.info(() => 123); + + expect(logs, hasLength(1)); + expect(logs.first.message, '123'); + }); + }); + }); +} + +class _CapturedLog { + final String name; + final SentryLevel level; + final String message; + final Object? error; + final StackTrace? stackTrace; + + _CapturedLog({ + required this.name, + required this.level, + required this.message, + this.error, + this.stackTrace, + }); +} + +class _TestMessage { + final String value; + + _TestMessage(this.value); + + @override + String toString() => 'TestMessage: $value'; +} diff --git a/packages/flutter/lib/src/isolate/isolate_logger.dart b/packages/flutter/lib/src/isolate/isolate_logger.dart deleted file mode 100644 index 2b6d8c3667..0000000000 --- a/packages/flutter/lib/src/isolate/isolate_logger.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'dart:developer' as developer; - -import 'package:meta/meta.dart'; - -import '../../sentry_flutter.dart'; - -/// Static logger for Isolates that writes diagnostic messages to `dart:developer.log`. -/// -/// Intended for worker/background isolates where a `SentryOptions` instance -/// or hub may not be available. Because Dart statics are isolate-local, -/// you must call [configure] once per isolate before using [log]. -class IsolateLogger { - IsolateLogger._(); - - static late bool _debug; - static late SentryLevel _level; - static late String _loggerName; - static bool _isConfigured = false; - - /// Configures this logger for the current isolate. - /// - /// Must be called once per isolate before invoking [log]. - /// Throws [StateError] if called more than once without calling [reset] first. - /// - /// - [debug]: when false, suppresses all logs except [SentryLevel.fatal]. - /// - [level]: minimum severity threshold (inclusive) when [debug] is true. - /// - [loggerName]: logger name for the call sites - static void configure( - {required bool debug, - required SentryLevel level, - required String loggerName}) { - if (_isConfigured) { - throw StateError( - 'IsolateLogger.configure has already been called. It can only be configured once per isolate.'); - } - _debug = debug; - _level = level; - _loggerName = loggerName; - _isConfigured = true; - } - - /// Resets the logger state to allow reconfiguration. - /// - /// This is intended for testing purposes only. - @visibleForTesting - static void reset() { - _isConfigured = false; - } - - /// Emits a log entry if enabled. - /// - /// Messages are forwarded to [developer.log]. The provided [level] is - /// mapped via [SentryLevel.toDartLogLevel] to a `developer.log` numeric level. - /// If logging is disabled or [level] is below the configured threshold, - /// nothing is emitted. [SentryLevel.fatal] is always emitted. - static void log( - SentryLevel level, - String message, { - String? logger, - Object? exception, - StackTrace? stackTrace, - }) { - assert( - _isConfigured, 'IsolateLogger.configure must be called before logging'); - if (_isEnabled(level)) { - developer.log( - '[${level.name}] $message', - level: level.toDartLogLevel(), - name: logger ?? _loggerName, - time: DateTime.now(), - error: exception, - stackTrace: stackTrace, - ); - } - } - - static bool _isEnabled(SentryLevel level) { - return (_debug && level.ordinal >= _level.ordinal) || - level == SentryLevel.fatal; - } -} diff --git a/packages/flutter/lib/src/isolate/isolate_worker.dart b/packages/flutter/lib/src/isolate/isolate_worker.dart index 8b3b375393..3057541d43 100644 --- a/packages/flutter/lib/src/isolate/isolate_worker.dart +++ b/packages/flutter/lib/src/isolate/isolate_worker.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:isolate'; import '../../sentry_flutter.dart'; -import 'isolate_logger.dart'; +import '../utils/internal_logger.dart'; typedef SpawnWorkerFn = Future Function(WorkerConfig, WorkerEntry); @@ -141,20 +141,18 @@ void runWorker( SendPort host, WorkerHandler handler, ) { - IsolateLogger.configure( - debug: config.debug, - level: config.diagnosticLevel, - loggerName: config.debugName, - ); + // ignore: invalid_use_of_internal_member + SentryInternalLogger.configure( + isEnabled: config.debug, minLevel: config.diagnosticLevel); final inbox = ReceivePort(); host.send(inbox.sendPort); inbox.listen((msg) async { if (msg == _shutdownCommand) { - IsolateLogger.log(SentryLevel.debug, 'Isolate received shutdown'); + internalLogger.debug('${config.debugName}: isolate received shutdown'); inbox.close(); - IsolateLogger.log(SentryLevel.debug, 'Isolate closed'); + internalLogger.debug('${config.debugName}: isolate closed'); return; } @@ -172,8 +170,10 @@ void runWorker( try { await handler.onMessage(msg); } catch (exception, stackTrace) { - IsolateLogger.log(SentryLevel.error, 'Isolate failed to handle message', - exception: exception, stackTrace: stackTrace); + internalLogger.error( + '${config.debugName}: isolate failed to handle message', + error: exception, + stackTrace: stackTrace); } }); } diff --git a/packages/flutter/lib/src/native/java/android_envelope_sender.dart b/packages/flutter/lib/src/native/java/android_envelope_sender.dart index 88e73c37f1..344d2e5153 100644 --- a/packages/flutter/lib/src/native/java/android_envelope_sender.dart +++ b/packages/flutter/lib/src/native/java/android_envelope_sender.dart @@ -7,7 +7,7 @@ import 'package:meta/meta.dart'; import '../../../sentry_flutter.dart'; import '../../isolate/isolate_worker.dart'; -import '../../isolate/isolate_logger.dart'; +import '../../utils/internal_logger.dart'; import 'binding.dart' as native; class AndroidEnvelopeSender { @@ -74,7 +74,8 @@ class _AndroidEnvelopeHandler extends WorkerHandler { final data = transferable.materialize().asUint8List(); _captureEnvelope(data, containsUnhandledException); } else { - IsolateLogger.log(SentryLevel.warning, 'Unexpected message type: $msg'); + internalLogger + .warning('${_config.debugName}: unexpected message type: $msg'); } } @@ -88,12 +89,12 @@ class _AndroidEnvelopeHandler extends WorkerHandler { byteArray, containsUnhandledException); if (id == null) { - IsolateLogger.log(SentryLevel.error, - 'Native Android SDK returned null when capturing envelope'); + internalLogger.error( + '${_config.debugName}: native Android SDK returned null when capturing envelope'); } } catch (exception, stackTrace) { - IsolateLogger.log(SentryLevel.error, 'Failed to capture envelope', - exception: exception, stackTrace: stackTrace); + internalLogger.error('${_config.debugName}: failed to capture envelope', + error: exception, stackTrace: stackTrace); if (_config.automatedTestMode) { rethrow; } diff --git a/packages/flutter/lib/src/native/java/android_replay_recorder.dart b/packages/flutter/lib/src/native/java/android_replay_recorder.dart index a7f31f7271..38b7006ea7 100644 --- a/packages/flutter/lib/src/native/java/android_replay_recorder.dart +++ b/packages/flutter/lib/src/native/java/android_replay_recorder.dart @@ -6,10 +6,10 @@ import 'package:jni/jni.dart'; import 'package:meta/meta.dart'; import '../../../sentry_flutter.dart'; -import '../../isolate/isolate_logger.dart'; import '../../isolate/isolate_worker.dart'; import '../../replay/scheduled_recorder.dart'; import '../../screenshot/screenshot.dart'; +import '../../utils/internal_logger.dart'; import 'binding.dart' as native; // Note, this is currently not unit-tested because mocking JNI calls is @@ -105,15 +105,15 @@ class _AndroidReplayHandler extends WorkerHandler { @override FutureOr onMessage(Object? message) { - IsolateLogger.log( - SentryLevel.warning, 'Unexpected fire-and-forget message: $message'); + internalLogger.warning( + '${_config.debugName}: Unexpected fire-and-forget message: $message'); } @override FutureOr onRequest(Object? payload) { if (payload is! _WorkItem) { - IsolateLogger.log( - SentryLevel.warning, 'Unexpected payload type: $payload'); + internalLogger + .warning('${_config.debugName}: Unexpected payload type: $payload'); return null; } @@ -142,8 +142,8 @@ class _AndroidReplayHandler extends WorkerHandler { return null; } catch (exception, stackTrace) { - IsolateLogger.log(SentryLevel.error, 'Failed to add replay screenshot', - exception: exception, stackTrace: stackTrace); + internalLogger.error('Failed to add replay screenshot', + error: exception, stackTrace: stackTrace); if (_config.automatedTestMode) { rethrow; } diff --git a/packages/flutter/lib/src/utils/internal_logger.dart b/packages/flutter/lib/src/utils/internal_logger.dart new file mode 100644 index 0000000000..9520a05ba7 --- /dev/null +++ b/packages/flutter/lib/src/utils/internal_logger.dart @@ -0,0 +1,6 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +/// Logger for the Sentry Flutter SDK. +@internal +const internalLogger = SentryInternalLogger('sentry_flutter'); diff --git a/packages/flutter/test/isolate/isolate_logger_test.dart b/packages/flutter/test/isolate/isolate_logger_test.dart deleted file mode 100644 index 5d6fddfc96..0000000000 --- a/packages/flutter/test/isolate/isolate_logger_test.dart +++ /dev/null @@ -1,70 +0,0 @@ -@TestOn('vm') -library; - -import 'dart:isolate'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:sentry_flutter/src/isolate/isolate_logger.dart'; - -void _entryUnconfigured(SendPort sendPort) { - try { - IsolateLogger.log(SentryLevel.info, 'x'); - sendPort.send('no-error'); - } catch (e) { - sendPort.send(e.runtimeType.toString()); - } -} - -void main() { - setUp(() { - IsolateLogger.reset(); - }); - - test('configure required before log (debug builds)', () async { - final rp = ReceivePort(); - await Isolate.spawn(_entryUnconfigured, rp.sendPort, - debugName: 'LoggerUnconfigured'); - final result = await rp.first; - rp.close(); - - expect(result, '_AssertionError'); - }); - - test('fatal logs even when debug=false', () { - IsolateLogger.configure( - debug: false, - level: SentryLevel.error, - loggerName: 't', - ); - expect(() => IsolateLogger.log(SentryLevel.fatal, 'fatal ok'), - returnsNormally); - }); - - test('threshold gating (no-throw at info below warning)', () { - IsolateLogger.configure( - debug: true, - level: SentryLevel.warning, - loggerName: 't', - ); - expect( - () => IsolateLogger.log(SentryLevel.info, 'info ok'), returnsNormally); - expect(() => IsolateLogger.log(SentryLevel.warning, 'warn ok'), - returnsNormally); - }); - - test('prevents reconfiguration without reset', () { - IsolateLogger.configure( - debug: true, - level: SentryLevel.info, - loggerName: 't', - ); - expect( - () => IsolateLogger.configure( - debug: false, - level: SentryLevel.error, - loggerName: 't2', - ), - throwsStateError); - }); -} From ea06d234e47203ec764459497192738716fc4de3 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 5 Jan 2026 16:17:25 +0100 Subject: [PATCH 04/62] fix(android): Envelope worker not starting when `autoInitializeNativeSdk` is disabled (#3420) * Update * Update CHANGELOG * Enhance AndroidEnvelopeSender to buffer envelopes when worker is not started and flush them upon starting. Update tests to reflect new buffering behavior and log changes from warning to info level. * Refactor SentryNativeJava tests: Split tests into separate files for VM and web environments. Introduce new test file for SentryNativeJava with ReplaySizeAdjustment and EnvelopeSender initialization tests. Remove redundant web stubs and streamline imports. * Refactor AndroidEnvelopeSender: Remove pending envelopes buffering and streamline envelope capture logic. Ensure envelopes are sent directly when the worker is available, and adjust logging for envelope capture in the main isolate. Update SentryNativeJava to start the envelope sender conditionally. * Enhance AndroidEnvelopeSender to manage closed state and improve envelope capture logic. Introduce a flag to prevent envelope capture after closure and update logging to use a required logger parameter. Adjust tests to reflect changes in behavior when the worker is not started. * Refactor AndroidEnvelopeSender: Adjust captureEnvelope method to ensure client assignment occurs after closed state check. This change improves clarity and maintains the integrity of the envelope sending process. * Fix AndroidEnvelopeSender start method to prevent spawning a worker if already closed. Update tests to reflect the expected spawn count when the sender is closed. * Update Android envelope capture test to assert behavior when the native channel is unavailable. Introduced a matcher for improved error handling in the captureEnvelope method. * Refactor AndroidEnvelopeSender start method to ensure proper closure handling during worker spawning. Introduce a guard clause to close the worker if the sender is already closed, enhancing stability and preventing resource leaks. * Refactor AndroidEnvelopeSender test to clarify logging behavior when sending envelopes in the main isolate. Update test description for improved readability and understanding of the expected functionality. * refactor(AndroidEnvelopeSender): update constructor to use SentryOptions and improve logging This commit refactors the `AndroidEnvelopeSender` class to replace the `_options` parameter with `SentryOptions` in the constructor. It also enhances the logging mechanism by utilizing `internalLogger` for logging messages related to envelope capture. The `_captureEnvelope` method has been updated to streamline error handling and improve clarity in logging, ensuring better maintainability and consistency across the codebase. * refactor(AndroidEnvelopeSender test): enhance logging configuration for envelope sending This commit updates the logging mechanism in the `AndroidEnvelopeSender` test to utilize the new `SentryInternalLogger`. The changes include removing the previous debug options and configuring the logger to capture logs with improved structure and clarity. This refactor aims to enhance the maintainability and consistency of logging behavior during envelope sending in the main isolate. --- CHANGELOG.md | 6 + .../native/java/android_envelope_sender.dart | 90 +++++++++------ .../src/native/java/sentry_native_java.dart | 12 +- .../android_envelope_sender_test_real.dart | 50 +++----- .../android_envelope_sender_test_web.dart | 11 +- .../test/native/sentry_native_java_test.dart | 51 +-------- .../native/sentry_native_java_test_real.dart | 108 ++++++++++++++++++ .../native/sentry_native_java_test_web.dart | 5 + .../test/sentry_native_channel_test.dart | 4 +- 9 files changed, 203 insertions(+), 134 deletions(-) create mode 100644 packages/flutter/test/native/sentry_native_java_test_real.dart create mode 100644 packages/flutter/test/native/sentry_native_java_test_web.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index ca2accebf7..f06f3785e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Android not sending events when `autoInitializedNativeSdk` is disabled ([#3420](https://github.com/getsentry/sentry-dart/pull/3420)) + ## 9.9.1 ### Fixes diff --git a/packages/flutter/lib/src/native/java/android_envelope_sender.dart b/packages/flutter/lib/src/native/java/android_envelope_sender.dart index 344d2e5153..c5bf9669a6 100644 --- a/packages/flutter/lib/src/native/java/android_envelope_sender.dart +++ b/packages/flutter/lib/src/native/java/android_envelope_sender.dart @@ -11,17 +11,19 @@ import '../../utils/internal_logger.dart'; import 'binding.dart' as native; class AndroidEnvelopeSender { - final SentryFlutterOptions _options; final WorkerConfig _config; final SpawnWorkerFn _spawn; + + bool _isClosed = false; Worker? _worker; - AndroidEnvelopeSender(this._options, {SpawnWorkerFn? spawn}) + AndroidEnvelopeSender(SentryOptions options, {SpawnWorkerFn? spawn}) : _config = WorkerConfig( debugName: 'SentryAndroidEnvelopeSender', - debug: _options.debug, - diagnosticLevel: _options.diagnosticLevel, - automatedTestMode: _options.automatedTestMode, + debug: options.debug, + diagnosticLevel: options.diagnosticLevel, + // ignore: invalid_use_of_internal_member + automatedTestMode: options.automatedTestMode, ), _spawn = spawn ?? spawnWorker; @@ -30,30 +32,41 @@ class AndroidEnvelopeSender { AndroidEnvelopeSender.new; FutureOr start() async { + if (_isClosed) return; if (_worker != null) return; - _worker = await _spawn(_config, _entryPoint); + final worker = await _spawn(_config, _entryPoint); + // Guard against close() being called during spawn. + if (_isClosed) { + worker.close(); + return; + } + _worker = worker; } FutureOr close() { _worker?.close(); _worker = null; + _isClosed = true; } /// Fire-and-forget send of envelope bytes to the worker. void captureEnvelope( Uint8List envelopeData, bool containsUnhandledException) { + if (_isClosed) return; + final client = _worker; - if (client == null) { - _options.log( - SentryLevel.warning, - 'captureEnvelope called before worker started; dropping', + if (client != null) { + client.send(( + TransferableTypedData.fromList([envelopeData]), + containsUnhandledException + )); + } else { + internalLogger.info( + 'captureEnvelope called before worker started: sending envelope in main isolate instead', ); - return; + _captureEnvelope(envelopeData, containsUnhandledException, + automatedTestMode: _config.automatedTestMode); } - client.send(( - TransferableTypedData.fromList([envelopeData]), - containsUnhandledException - )); } static void _entryPoint((SendPort, WorkerConfig) init) { @@ -72,35 +85,36 @@ class _AndroidEnvelopeHandler extends WorkerHandler { if (msg is (TransferableTypedData, bool)) { final (transferable, containsUnhandledException) = msg; final data = transferable.materialize().asUint8List(); - _captureEnvelope(data, containsUnhandledException); + _captureEnvelope(data, containsUnhandledException, + automatedTestMode: _config.automatedTestMode); } else { internalLogger .warning('${_config.debugName}: unexpected message type: $msg'); } } +} - void _captureEnvelope( - Uint8List envelopeData, bool containsUnhandledException) { - JObject? id; - JByteArray? byteArray; - try { - byteArray = JByteArray.from(envelopeData); - id = native.InternalSentrySdk.captureEnvelope( - byteArray, containsUnhandledException); - - if (id == null) { - internalLogger.error( - '${_config.debugName}: native Android SDK returned null when capturing envelope'); - } - } catch (exception, stackTrace) { - internalLogger.error('${_config.debugName}: failed to capture envelope', - error: exception, stackTrace: stackTrace); - if (_config.automatedTestMode) { - rethrow; - } - } finally { - byteArray?.release(); - id?.release(); +void _captureEnvelope(Uint8List envelopeData, bool containsUnhandledException, + {bool automatedTestMode = false}) { + JObject? id; + JByteArray? byteArray; + try { + byteArray = JByteArray.from(envelopeData); + id = native.InternalSentrySdk.captureEnvelope( + byteArray, containsUnhandledException); + + if (id == null) { + internalLogger + .error('Native Android SDK returned null when capturing envelope'); + } + } catch (exception, stackTrace) { + internalLogger.error('Failed to capture envelope', + error: exception, stackTrace: stackTrace); + if (automatedTestMode) { + rethrow; } + } finally { + byteArray?.release(); + id?.release(); } } 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 e2c7a773eb..5f56f35040 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java.dart @@ -23,7 +23,12 @@ class SentryNativeJava extends SentryNativeChannel { AndroidEnvelopeSender? _envelopeSender; native.ReplayIntegration? _nativeReplay; - SentryNativeJava(super.options); + SentryNativeJava(super.options) { + // Initialize envelope sender here in the ctor instead of init(). + // Ensures it starts when autoInitializeNativeSdk is enabled and disabled. + _envelopeSender = AndroidEnvelopeSender.factory(options); + _envelopeSender?.start(); + } @override bool get supportsReplay => true; @@ -36,11 +41,8 @@ class SentryNativeJava extends SentryNativeChannel { AndroidReplayRecorder? get testRecorder => _replayRecorder; @override - Future init(Hub hub) async { + void init(Hub hub) { initSentryAndroid(hub: hub, options: options, owner: this); - - _envelopeSender = AndroidEnvelopeSender.factory(options); - await _envelopeSender?.start(); } @override diff --git a/packages/flutter/test/native/android_envelope_sender_test_real.dart b/packages/flutter/test/native/android_envelope_sender_test_real.dart index 64067db2bb..d2b12732a9 100644 --- a/packages/flutter/test/native/android_envelope_sender_test_real.dart +++ b/packages/flutter/test/native/android_envelope_sender_test_real.dart @@ -12,23 +12,31 @@ import 'package:sentry_flutter/src/isolate/isolate_worker.dart'; void main() { group('AndroidEnvelopeSender host behavior', () { - test('warns and drops when not started', () { + test('logs when sending envelopes in main isolate', () { final options = SentryFlutterOptions(); - options.debug = true; - options.diagnosticLevel = SentryLevel.debug; final logs = <(SentryLevel, String)>[]; - options.log = (level, message, {logger, exception, stackTrace}) { - logs.add((level, message)); - }; + SentryInternalLogger.configure( + isEnabled: true, + minLevel: SentryLevel.debug, + logOutput: ({ + required String name, + required SentryLevel level, + required String message, + Object? error, + StackTrace? stackTrace, + }) { + logs.add((level, message.toString())); + }, + ); final sender = AndroidEnvelopeSender(options); sender.captureEnvelope(Uint8List.fromList([1, 2, 3]), false); expect( logs.any((e) => - e.$1 == SentryLevel.warning && + e.$1 == SentryLevel.info && e.$2.contains( - 'captureEnvelope called before worker started; dropping')), + 'captureEnvelope called before worker started: sending envelope in main isolate instead')), isTrue, ); }); @@ -40,30 +48,6 @@ void main() { expect(() => sender.close(), returnsNormally); }); - test('warns and drops after close', () async { - final options = SentryFlutterOptions(); - options.debug = true; - options.diagnosticLevel = SentryLevel.debug; - final logs = <(SentryLevel, String)>[]; - options.log = (level, message, {logger, exception, stackTrace}) { - logs.add((level, message)); - }; - - final sender = AndroidEnvelopeSender(options); - await sender.start(); - sender.close(); - - sender.captureEnvelope(Uint8List.fromList([9]), false); - - expect( - logs.any((e) => - e.$1 == SentryLevel.warning && - e.$2.contains( - 'captureEnvelope called before worker started; dropping')), - isTrue, - ); - }); - test('start is a no-op when already started', () async { final options = SentryFlutterOptions(); options.debug = true; @@ -88,7 +72,7 @@ void main() { spawnCount = 0; await sender.start(); - expect(spawnCount, 1); + expect(spawnCount, 0); // Close twice should be safe. expect(() => sender.close(), returnsNormally); diff --git a/packages/flutter/test/native/android_envelope_sender_test_web.dart b/packages/flutter/test/native/android_envelope_sender_test_web.dart index 6b061ee80a..3a62a53377 100644 --- a/packages/flutter/test/native/android_envelope_sender_test_web.dart +++ b/packages/flutter/test/native/android_envelope_sender_test_web.dart @@ -1,10 +1,5 @@ -// Stub for web - these tests only run on VM -import 'package:flutter_test/flutter_test.dart'; - void main() { - test('Android envelope sender tests are not supported on web', () { - // This test file exists only to satisfy the compiler when running web tests. - // The actual tests in android_envelope_sender_test_real.dart are only - // executed on VM platforms. - }); + // This test file exists only to satisfy the compiler when running web tests. + // The actual tests in android_envelope_sender_test_real.dart are only + // executed on VM platforms. } diff --git a/packages/flutter/test/native/sentry_native_java_test.dart b/packages/flutter/test/native/sentry_native_java_test.dart index a11e552fa6..5e6285f1b0 100644 --- a/packages/flutter/test/native/sentry_native_java_test.dart +++ b/packages/flutter/test/native/sentry_native_java_test.dart @@ -1,49 +1,2 @@ -@TestOn('vm') -library; - -import 'package:flutter_test/flutter_test.dart'; -import 'sentry_native_java_web_stub.dart' - if (dart.library.io) 'package:sentry_flutter/src/native/java/sentry_native_java.dart'; - -void main() { - // the ReplaySizeAdjustment tests assumes a constant video block size of 16 - group('ReplaySizeAdjustment', () { - test('rounds down when remainder is less than or equal to half block size', - () { - expect(0.0.adjustReplaySizeToBlockSize(), 0.0); - expect(8.0.adjustReplaySizeToBlockSize(), 0.0); - expect(16.0.adjustReplaySizeToBlockSize(), 16.0); - expect(24.0.adjustReplaySizeToBlockSize(), 16.0); - expect(100.0.adjustReplaySizeToBlockSize(), 96.0); - }); - - test('rounds up when remainder is greater than half block size', () { - expect(9.0.adjustReplaySizeToBlockSize(), 16.0); - expect(15.0.adjustReplaySizeToBlockSize(), 16.0); - expect(25.0.adjustReplaySizeToBlockSize(), 32.0); - expect(108.0.adjustReplaySizeToBlockSize(), 112.0); - expect(109.0.adjustReplaySizeToBlockSize(), 112.0); - }); - - test('returns exact value when already multiple of block size', () { - expect(32.0.adjustReplaySizeToBlockSize(), 32.0); - expect(48.0.adjustReplaySizeToBlockSize(), 48.0); - expect(64.0.adjustReplaySizeToBlockSize(), 64.0); - expect(128.0.adjustReplaySizeToBlockSize(), 128.0); - }); - - test('handles edge cases at half block size boundaries', () { - expect(8.0.adjustReplaySizeToBlockSize(), 0.0); - expect(24.0.adjustReplaySizeToBlockSize(), 16.0); - expect(40.0.adjustReplaySizeToBlockSize(), 32.0); - }); - - test('handles fractional values', () { - expect(7.5.adjustReplaySizeToBlockSize(), 0.0); - expect(8.5.adjustReplaySizeToBlockSize(), 16.0); - expect(15.5.adjustReplaySizeToBlockSize(), 16.0); - expect(16.5.adjustReplaySizeToBlockSize(), 16.0); - expect(24.5.adjustReplaySizeToBlockSize(), 32.0); - }); - }); -} +export 'sentry_native_java_test_real.dart' + if (dart.library.js_interop) 'sentry_native_java_test_web.dart'; diff --git a/packages/flutter/test/native/sentry_native_java_test_real.dart b/packages/flutter/test/native/sentry_native_java_test_real.dart new file mode 100644 index 0000000000..d320852b23 --- /dev/null +++ b/packages/flutter/test/native/sentry_native_java_test_real.dart @@ -0,0 +1,108 @@ +@TestOn('vm') +// ignore_for_file: invalid_use_of_internal_member +library; + +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_flutter/src/native/java/android_envelope_sender.dart'; +import 'package:sentry_flutter/src/native/java/sentry_native_java.dart'; + +void main() { + // the ReplaySizeAdjustment tests assumes a constant video block size of 16 + group('ReplaySizeAdjustment', () { + test('rounds down when remainder is less than or equal to half block size', + () { + expect(0.0.adjustReplaySizeToBlockSize(), 0.0); + expect(8.0.adjustReplaySizeToBlockSize(), 0.0); + expect(16.0.adjustReplaySizeToBlockSize(), 16.0); + expect(24.0.adjustReplaySizeToBlockSize(), 16.0); + expect(100.0.adjustReplaySizeToBlockSize(), 96.0); + }); + + test('rounds up when remainder is greater than half block size', () { + expect(9.0.adjustReplaySizeToBlockSize(), 16.0); + expect(15.0.adjustReplaySizeToBlockSize(), 16.0); + expect(25.0.adjustReplaySizeToBlockSize(), 32.0); + expect(108.0.adjustReplaySizeToBlockSize(), 112.0); + expect(109.0.adjustReplaySizeToBlockSize(), 112.0); + }); + + test('returns exact value when already multiple of block size', () { + expect(32.0.adjustReplaySizeToBlockSize(), 32.0); + expect(48.0.adjustReplaySizeToBlockSize(), 48.0); + expect(64.0.adjustReplaySizeToBlockSize(), 64.0); + expect(128.0.adjustReplaySizeToBlockSize(), 128.0); + }); + + test('handles edge cases at half block size boundaries', () { + expect(8.0.adjustReplaySizeToBlockSize(), 0.0); + expect(24.0.adjustReplaySizeToBlockSize(), 16.0); + expect(40.0.adjustReplaySizeToBlockSize(), 32.0); + }); + + test('handles fractional values', () { + expect(7.5.adjustReplaySizeToBlockSize(), 0.0); + expect(8.5.adjustReplaySizeToBlockSize(), 16.0); + expect(15.5.adjustReplaySizeToBlockSize(), 16.0); + expect(16.5.adjustReplaySizeToBlockSize(), 16.0); + expect(24.5.adjustReplaySizeToBlockSize(), 32.0); + }); + }); + + group('EnvelopeSender initialization', () { + late AndroidEnvelopeSender Function(SentryFlutterOptions) originalFactory; + + setUp(() { + originalFactory = AndroidEnvelopeSender.factory; + }); + + tearDown(() { + AndroidEnvelopeSender.factory = originalFactory; + }); + + test('starts envelope sender in constructor', () { + var factoryCalled = false; + var startCalled = false; + + AndroidEnvelopeSender.factory = (options) { + factoryCalled = true; + return _FakeEnvelopeSender(onStart: () => startCalled = true); + }; + + final options = + SentryFlutterOptions(dsn: 'https://abc@def.ingest.sentry.io/1234567'); + SentryNativeJava(options); + + expect(factoryCalled, isTrue, + reason: 'Factory should be called during construction'); + expect(startCalled, isTrue, + reason: 'start() should be called during construction'); + }); + }); +} + +/// Fake envelope sender for testing that tracks method calls. +class _FakeEnvelopeSender implements AndroidEnvelopeSender { + final void Function()? onStart; + + _FakeEnvelopeSender({this.onStart}); + + @override + FutureOr start() { + onStart?.call(); + } + + @override + FutureOr close() { + // No-op for testing + } + + @override + void captureEnvelope( + Uint8List envelopeData, bool containsUnhandledException) { + // No-op for testing + } +} diff --git a/packages/flutter/test/native/sentry_native_java_test_web.dart b/packages/flutter/test/native/sentry_native_java_test_web.dart new file mode 100644 index 0000000000..e077692e8a --- /dev/null +++ b/packages/flutter/test/native/sentry_native_java_test_web.dart @@ -0,0 +1,5 @@ +void main() { + // This test file exists only to satisfy the compiler when running web tests. + // The actual tests in sentry_native_java_test_real.dart are only + // executed on VM platforms. +} diff --git a/packages/flutter/test/sentry_native_channel_test.dart b/packages/flutter/test/sentry_native_channel_test.dart index cc634c4016..3d2a590ea1 100644 --- a/packages/flutter/test/sentry_native_channel_test.dart +++ b/packages/flutter/test/sentry_native_channel_test.dart @@ -328,9 +328,11 @@ void main() { test('captureEnvelope', () async { if (mockPlatform.isAndroid) { + final matcher = _nativeUnavailableMatcher(); + final data = Uint8List.fromList([1, 2, 3]); - await sut.captureEnvelope(data, false); + expect(() => sut.captureEnvelope(data, false), matcher); verifyZeroInteractions(channel); } else { From 96fefbffbc3ea4617b7b78a77d0c049ae07adb55 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 5 Jan 2026 15:29:55 +0000 Subject: [PATCH 05/62] release: 9.9.2 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f06f3785e3..c4e4870171 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.9.2 ### Fixes diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index 2a65d72e43..e7500806ed 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.9.2 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.1 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.0-beta.4 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index cb976e13bf..9f4de328d0 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 0d9c06cdac..c7ed392184 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.9.1 +version: 9.9.2 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index 19ffe1e8ab..a6e5757ec8 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index 3c6eaa415c..f0fc180c71 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.9.1 + sentry: 9.9.2 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index 5e0a44ab94..1617c084cc 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 11742cec39..3e05459fdb 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.9.1 + sentry: 9.9.2 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 1c722c25b3..9c8e3ac051 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index f04d0dc4f0..a6af6fa782 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.9.1 + sentry: 9.9.2 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index aa6edb8419..d2fdedecf1 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.9.1 + sentry: 9.9.2 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index 3fd2056987..f1a47ac549 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.9.1 +version: 9.9.2 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 21a248f538..73989c208c 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index e3a22f6f01..ef890b9260 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.9.1 +version: 9.9.2 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.9.1 + sentry: 9.9.2 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index d3d4f22cfd..73de810436 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index d5f9dc01e5..b366ebe711 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.9.1 + sentry: 9.9.2 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index 9a905944fc..35b5137d23 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index fa8935f20a..0e31e77dfd 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.9.1 + sentry: 9.9.2 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index a14b74fa85..85f648270c 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.9.1 + sentry: 9.9.2 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index 8992f22ba5..d63cbd8707 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index 39d9ddb774..cf7eb3ebbf 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.9.1 + sentry: 9.9.2 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index 77e774c4ca..ed17928067 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.1'; +const String sdkVersion = '9.9.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index 119eeb23f3..b687f9c6f2 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.9.1 + sentry: 9.9.2 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 86510ad992..97ff945ecd 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.9.1 +version: 9.9.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -10,7 +10,7 @@ environment: dependencies: http: ^1.3.0 - sentry: 9.9.1 + sentry: 9.9.2 dev_dependencies: supabase: ^2.6.0 From c41dfe25d72103504e6183cd2263137d84bd732c Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 7 Jan 2026 13:04:50 +0100 Subject: [PATCH 06/62] chore(agents): Add `AGENTS.md` (#3426) * Update * Refine test naming conventions in AGENTS.md for improved clarity and structure - Updated guidelines to ensure test group and test names read as coherent sentences. - Introduced a structured approach for naming by depth, emphasizing the use of subjects, contexts, variants, and behaviors. - Added examples and anti-patterns to illustrate best practices in test organization and naming. * Enhance Dart code design guidelines in AGENTS.md - Added comprehensive guidelines for identifiers, ordering, formatting, comments, and documentation to improve code consistency and readability. - Included best practices for naming conventions, code structure, and documentation styles to align with the Effective Dart guide. - Emphasized the importance of adhering to these guidelines for new and modified tests. * Refactor AGENTS.md for improved clarity and structure - Streamlined project structure section by removing table format for a more concise list format. - Updated environment section to include specific Flutter and Dart versions. - Enhanced testing guidelines with clearer commands and descriptions for Dart and Flutter packages. - Added new guidelines for modern Dart language features to promote clarity and reduce boilerplate in code. * Enhance agent documentation and testing guidelines - Updated AGENTS.md to clarify the structure and purpose of the Sentry Dart/Flutter SDK. - Introduced new documentation files for code guidelines and test conventions, emphasizing best practices for Dart/Flutter development. - Added detailed sections on naming conventions, test structure, and the use of modern Dart features to improve code clarity and maintainability. - Ensured that all new and modified code adheres to these updated guidelines for consistency across the project. * Update documentation comments guidelines in code-guidelines.md - Renamed section from "Doc Comments" to "Documentation Comments" for clarity. - Added recommendations for when to write comments, emphasizing the importance of self-documenting code. - Included specific guidelines on documenting public APIs and non-obvious reasoning, while advising against commenting on obvious behavior and providing excessive inline commentary. --- AGENTS.md | 62 ++++++++ docs/agent_instructions/code-guidelines.md | 152 ++++++++++++++++++++ docs/agent_instructions/test-conventions.md | 109 ++++++++++++++ 3 files changed, 323 insertions(+) create mode 100644 AGENTS.md create mode 100644 docs/agent_instructions/code-guidelines.md create mode 100644 docs/agent_instructions/test-conventions.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..7af000e37f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,62 @@ +# Sentry Dart/Flutter SDK - Agent Guide + +## Overview + +Sentry is a developer-first error tracking and performance monitoring platform. +This repository contains the Sentry Dart/Flutter SDK and integrations. + +## Project Structure + +- `packages/dart/` - Core Sentry Dart SDK +- `packages/flutter/` - Sentry Flutter SDK (includes native integrations) +- `packages/dio/` - Dio HTTP client integration +- `packages/drift/` - Drift database integration +- `packages/file/` - File I/O integration +- `packages/hive/` - Hive database integration +- `packages/isar/` - Isar database integration +- `packages/sqflite/` - SQLite integration +- `packages/logging/` - Dart logging package integration +- `packages/supabase/` - Supabase integration +- `packages/firebase_remote_config/` - Firebase Remote Config integration +- `packages/link/` - Deep linking integration +- `docs/` - Documentation +- `e2e_test/` - End-to-end test suite +- `min_version_test/` - Minimum SDK version compatibility tests +- `metrics/` - Size and performance metrics tooling +- `scripts/` - Build, release, and utility scripts +- `melos.yaml` - Melos monorepo configuration + +## Environment + +- Flutter: `3.24.0` | Dart: `3.5.0` +- Use `fvm dart` / `fvm flutter` if available (check with `which fvm`), else `dart` / `flutter` + +### Package Types + +Check `pubspec.yaml` to determine package type: + +- **Dart-only**: No `flutter:` in `environment:` section (e.g., `sentry`, `sentry_dio`) +- **Flutter**: Has `flutter:` constraint (e.g., `sentry_flutter`, `sentry_sqflite`) + +### Commands + +Run from within the package directory (e.g., `packages/dart/`): + +- Test: `dart test` (Dart) or `flutter test` (Flutter) +- Analyze: `dart analyze` (Dart) or `flutter analyze` (Flutter) +- Format: `dart format ` +- Fix: `dart fix --apply` +- Web Test: `flutter test -d chrome` + +## Agent Documentation + +Read these files **only when relevant** to your current task: + +- `docs/agent_instructions/test-conventions.md` - Writing or modifying tests +- `docs/agent_instructions/code-guidelines.md` - Implementing new features, refactoring, or reviewing code + +## Key Principles + +- **Development**: Always ask clarifying questions if needed and/or propose a plan before implementation +- **Test First**: Write failing tests before implementation; fix regressions with a reproducing test first +- **Git Usage**: **NEVER** commit or push code diff --git a/docs/agent_instructions/code-guidelines.md b/docs/agent_instructions/code-guidelines.md new file mode 100644 index 0000000000..28f093f5bf --- /dev/null +++ b/docs/agent_instructions/code-guidelines.md @@ -0,0 +1,152 @@ +# Dart/Flutter Code Guidelines + +> **Note:** Existing code may not follow these conventions. New and modified code should adhere to these guidelines. + +Use only language features available in the Dart/Flutter versions specified in `AGENTS.md`. + +## SDK Development Rules + +### Integrations + +Encapsulate SDK features as `Integration` classes that implement `call()` and `close()`: + +- Check feature flags and prerequisites early, log and return if disabled +- Register the integration via `options.sdk.addIntegration(name)` +- Clean up resources in `close()` if needed +- See `packages/flutter/lib/src/integrations/` for examples +- Integrations should be order-independent; if yours requires running before/after another, reconsider the design + +### Privacy + +- Never collect Personally Identifiable Information (PII) without checking `options.sendDefaultPii` +- Flag any changes that could leak PII for review + +### Breaking Changes + +- Signal breaking changes clearly (API removals, behavior changes, renamed options) +- Prefer deprecation with migration path over immediate removal + +### Native Code (JNI/FFI) + +- Release all native memory (JNI local refs, malloc allocations) +- Handle native exceptions gracefully—don't crash the host app + +### File Organization + +- Prefer grouping related files by feature in sub-directories (e.g., `metrics/`) +- Avoid flat structures with many unrelated files in one directory + +## Modern Dart Features + +Prefer modern Dart language features (Dart 3.5+) when they improve clarity and reduce boilerplate: + +- **Sealed Classes** - Exhaustive pattern matching with restricted hierarchies +- **Extension Types** - Zero-cost wrappers around existing types +- **Records** - Lightweight multi-value returns: `(String, int)` or `({String name, int age})` +- **Pattern Matching** - Destructuring in `switch`, `if-case`, variable declarations +- **Switch Expressions** - Expression-based switches returning values +- **Class Modifiers** - `final`, `base`, `interface`, `mixin` class modifiers +- **Enhanced Enums** - Enums with fields, constructors, and methods +- **If-Case Expressions** - Pattern matching in if statements +- **Null-Aware Elements** - `?maybeNull` in collection literals + +## Semantic Naming Guidelines + +### General Naming + +- [DO use terms consistently.](https://dart.dev/effective-dart/design#do-use-terms-consistently) +- [AVOID abbreviations.](https://dart.dev/effective-dart/design#avoid-abbreviations) +- [PREFER putting the most descriptive noun last.](https://dart.dev/effective-dart/design#prefer-putting-the-most-descriptive-noun-last) +- [CONSIDER making the code read like a sentence.](https://dart.dev/effective-dart/design#consider-making-the-code-read-like-a-sentence) + +### Properties and Variables + +- [PREFER a noun phrase for a non-boolean property or variable.](https://dart.dev/effective-dart/design#prefer-a-noun-phrase-for-a-non-boolean-property-or-variable) +- [PREFER a non-imperative verb phrase for a boolean property or variable.](https://dart.dev/effective-dart/design#prefer-a-non-imperative-verb-phrase-for-a-boolean-property-or-variable) +- [CONSIDER omitting the verb for a named boolean _parameter_.](https://dart.dev/effective-dart/design#consider-omitting-the-verb-for-a-named-boolean-parameter) +- [PREFER the "positive" name for a boolean property or variable.](https://dart.dev/effective-dart/design#prefer-the-positive-name-for-a-boolean-property-or-variable) + +### Methods and Functions + +- [PREFER an imperative verb phrase for a function or method whose main purpose is a side effect.](https://dart.dev/effective-dart/design#prefer-an-imperative-verb-phrase-for-a-function-or-method-whose-main-purpose-is-a-side-effect) +- [PREFER a noun phrase or non-imperative verb phrase for a function or method if returning a value is its primary purpose.](https://dart.dev/effective-dart/design#prefer-a-noun-phrase-or-non-imperative-verb-phrase-for-a-function-or-method-if-returning-a-value-is-its-primary-purpose) +- [CONSIDER an imperative verb phrase for a function or method if you want to draw attention to the work it performs.](https://dart.dev/effective-dart/design#consider-an-imperative-verb-phrase-for-a-function-or-method-if-you-want-to-draw-attention-to-the-work-it-performs) +- [AVOID starting a method name with `get`.](https://dart.dev/effective-dart/design#avoid-starting-a-method-name-with-get) +- [PREFER naming a method `to___()` if it copies the object's state to a new object.](https://dart.dev/effective-dart/design#prefer-naming-a-method-to___-if-it-copies-the-objects-state-to-a-new-object) +- [PREFER naming a method `as___()` if it returns a different representation backed by the original object.](https://dart.dev/effective-dart/design#prefer-naming-a-method-as___-if-it-returns-a-different-representation-backed-by-the-original-object) +- [AVOID describing the parameters in the function's or method's name.](https://dart.dev/effective-dart/design#avoid-describing-the-parameters-in-the-functions-or-methods-name) + +### Type Parameters + +- [DO follow existing mnemonic conventions when naming type parameters.](https://dart.dev/effective-dart/design#do-follow-existing-mnemonic-conventions-when-naming-type-parameters) + +## Dart Code Design + +### Classes and Abstractions + +- [AVOID defining a one-member abstract class when a simple function will do.](https://dart.dev/effective-dart/design#avoid-defining-a-one-member-abstract-class-when-a-simple-function-will-do) +- [AVOID defining a class that contains only static members.](https://dart.dev/effective-dart/design#avoid-defining-a-class-that-contains-only-static-members) +- [DO use class modifiers to control if your class can be extended.](https://dart.dev/effective-dart/design#do-use-class-modifiers-to-control-if-your-class-can-be-extended) +- [DO use class modifiers to control if your class can be an interface.](https://dart.dev/effective-dart/design#do-use-class-modifiers-to-control-if-your-class-can-be-an-interface) +- [PREFER defining a pure `mixin` or pure `class` to a `mixin class`.](https://dart.dev/effective-dart/design#prefer-defining-a-pure-mixin-or-pure-class-to-a-mixin-class) +- [PREFER making declarations private.](https://dart.dev/effective-dart/design#prefer-making-declarations-private) + +### Asynchrony + +- [PREFER async/await over using raw futures.](https://dart.dev/effective-dart/usage#prefer-asyncawait-over-using-raw-futures) +- [CONSIDER using higher-order methods to transform a stream.](https://dart.dev/effective-dart/usage#consider-using-higher-order-methods-to-transform-a-stream) +- [AVOID using Completer directly.](https://dart.dev/effective-dart/usage#avoid-using-completer-directly) + +### Types and Nullability + +- [AVOID `late` variables if you need to check whether they are initialized.](https://dart.dev/effective-dart/usage#avoid-late-variables-if-you-need-to-check-whether-they-are-initialized) +- [CONSIDER type promotion or null-check patterns for using nullable types.](https://dart.dev/effective-dart/usage#consider-type-promotion-or-null-check-patterns-for-using-nullable-types) +- [DO use `Future` as the return type of asynchronous members that do not produce values.](https://dart.dev/effective-dart/design#do-use-futurevoid-as-the-return-type-of-asynchronous-members-that-do-not-produce-values) +- [AVOID returning nullable `Future`, `Stream`, and collection types.](https://dart.dev/effective-dart/design#avoid-returning-nullable-future-stream-and-collection-types) + +### Parameters + +- [AVOID positional boolean parameters.](https://dart.dev/effective-dart/design#avoid-positional-boolean-parameters) +- [AVOID optional positional parameters if the user may want to omit earlier parameters.](https://dart.dev/effective-dart/design#avoid-optional-positional-parameters-if-the-user-may-want-to-omit-earlier-parameters) +- [AVOID mandatory parameters that accept a special "no argument" value.](https://dart.dev/effective-dart/design#avoid-mandatory-parameters-that-accept-a-special-no-argument-value) +- [DO use inclusive start and exclusive end parameters to accept a range.](https://dart.dev/effective-dart/design#do-use-inclusive-start-and-exclusive-end-parameters-to-accept-a-range) + +### Equality + +- [DO override `hashCode` if you override `==`.](https://dart.dev/effective-dart/design#do-override-hashcode-if-you-override) +- [DO make your `==` operator obey the mathematical rules of equality.](https://dart.dev/effective-dart/design#do-make-your-operator-obey-the-mathematical-rules-of-equality) +- [AVOID defining custom equality for mutable classes.](https://dart.dev/effective-dart/design#avoid-defining-custom-equality-for-mutable-classes) + +### Documentation Comments + +Prefer self-documenting code—use clear names and structure so comments become unnecessary. + +#### Do Write Comment When + +- Public APIs—document for users who can't see the implementation +- Non-obvious "why" — explain reasoning not clear from code (workarounds, edge cases, constraints) + +#### Do Not Write Comment When + +- Obvious behavior — don't describe what code clearly does +- Inline play-by-play — avoid commenting every step in a method + +#### Style Rules + +- [AVOID redundancy with the surrounding context.](https://dart.dev/effective-dart/documentation#avoid-redundancy-with-the-surrounding-context) +- [DO use `///` doc comments to document members and types.](https://dart.dev/effective-dart/documentation#do-use-doc-comments-to-document-members-and-types) +- [PREFER writing doc comments for public APIs.](https://dart.dev/effective-dart/documentation#prefer-writing-doc-comments-for-public-apis) +- [CONSIDER writing a library-level doc comment.](https://dart.dev/effective-dart/documentation#consider-writing-a-library-level-doc-comment) +- [CONSIDER writing doc comments for private APIs.](https://dart.dev/effective-dart/documentation#consider-writing-doc-comments-for-private-apis) +- [DO start doc comments with a single-sentence summary.](https://dart.dev/effective-dart/documentation#do-start-doc-comments-with-a-single-sentence-summary) +- [DO separate the first sentence of a doc comment into its own paragraph.](https://dart.dev/effective-dart/documentation#do-separate-the-first-sentence-of-a-doc-comment-into-its-own-paragraph) +- [PREFER starting comments of a function or method with third-person verbs if its main purpose is a side effect.](https://dart.dev/effective-dart/documentation#prefer-starting-comments-of-a-function-or-method-with-third-person-verbs-if-its-main-purpose-is-a-side-effect) +- [PREFER starting a non-boolean variable or property comment with a noun phrase.](https://dart.dev/effective-dart/documentation#prefer-starting-a-non-boolean-variable-or-property-comment-with-a-noun-phrase) +- [PREFER starting a boolean variable or property comment with "Whether" followed by a noun or gerund phrase.](https://dart.dev/effective-dart/documentation#prefer-starting-a-boolean-variable-or-property-comment-with-whether-followed-by-a-noun-or-gerund-phrase) +- [PREFER a noun phrase or non-imperative verb phrase for a function or method if returning a value is its primary purpose.](https://dart.dev/effective-dart/documentation#prefer-a-noun-phrase-or-non-imperative-verb-phrase-for-a-function-or-method-if-returning-a-value-is-its-primary-purpose) +- [DON'T write documentation for both the getter and setter of a property.](https://dart.dev/effective-dart/documentation#dont-write-documentation-for-both-the-getter-and-setter-of-a-property) +- [PREFER starting library or type comments with noun phrases.](https://dart.dev/effective-dart/documentation#prefer-starting-library-or-type-comments-with-noun-phrases) +- [CONSIDER including code samples in doc comments.](https://dart.dev/effective-dart/documentation#consider-including-code-samples-in-doc-comments) +- [DO use square brackets in doc comments to refer to in-scope identifiers.](https://dart.dev/effective-dart/documentation#do-use-square-brackets-in-doc-comments-to-refer-to-in-scope-identifiers) +- [DO use prose to explain parameters, return values, and exceptions.](https://dart.dev/effective-dart/documentation#do-use-prose-to-explain-parameters-return-values-and-exceptions) +- [DO put doc comments before metadata annotations.](https://dart.dev/effective-dart/documentation#do-put-doc-comments-before-metadata-annotations) diff --git a/docs/agent_instructions/test-conventions.md b/docs/agent_instructions/test-conventions.md new file mode 100644 index 0000000000..6cf3dd9e72 --- /dev/null +++ b/docs/agent_instructions/test-conventions.md @@ -0,0 +1,109 @@ +# Test Conventions + +> **Note:** Existing tests may not follow these conventions. New and modified tests should adhere to these guidelines. + +## Structure + +**Rule:** Nested `group()` + `test()` names must read as a sentence when concatenated. + +Pattern: `[Subject] [Context] [Variant] [Behavior]` + +- Subject = noun (e.g., `Client`) +- Context = preposition phrase (e.g., `when connected`) +- Variant = condition (e.g., `with valid input`) +- Behavior = verb phrase (e.g., `sends message`) + +## Naming by Depth + +- Group 1 (Subject) - use Noun style - example: `Client` +- Group 2 (Context) - use `when / in / during` style - example: `when connected` +- Group 3 (Variant) - use `with / given / using` style - example: `with valid input` +- Test (Behavior) - use Verb phrase style - example: `sends message` + +## Depth Guidelines + +- **Maximum depth: 3 groups.** If you need more nesting, call out that this is a code smell and suggest refactoring the implementation. +- **Simple variants can go in the test name** instead of a separate group. Use a group only when multiple tests share the same variant setup. + +```dart +// ✅ Good: Simple variant in test name (2 groups + test) +group('Hub', () { + group('when bound to client', () { + test('with valid DSN initializes correctly', () { }); + test('with empty DSN throws exception', () { }); + }); +}); + +// ❌ Avoid: Unnecessary nesting for simple variants (3 groups + test) +group('Hub', () { + group('when bound to client', () { + group('with valid DSN', () { + test('initializes correctly', () { }); + }); + }); +}); +``` + +## Negative Tests + +Use clear verb phrases that indicate the absence of behavior or expected failures: + +- `does not ` - when behavior is intentionally skipped - example: `does not send event` +- `throws ` - when expecting an exception - example: `throws ArgumentError` +- `returns null` - when null result is expected - example: `returns null when missing` +- `ignores ` - when input is deliberately ignored - example: `ignores empty breadcrumbs` + +```dart +group('Client', () { + group('when disabled', () { + test('does not send events', () { }); + test('returns null for captureEvent', () { }); + }); +}); +``` + +## One-Line Check + +**If it doesn't read like a sentence, rename the groups.** + +```dart +// Subject → Behavior (1 group) +group('Hub', () { + test('returns the scope', () { }); +}); +// Reads: "Hub returns the scope" + +// Subject → Context → Behavior (2 groups) +group('Hub', () { + group('when capturing', () { + test('sends event to transport', () { }); + test('attaches breadcrumbs', () { }); + }); +}); +// Reads: "Hub when capturing sends event to transport" +``` + +## Fixture Pattern + +Use a `Fixture` class at the end of test files to encapsulate test setup: + +```dart +class Fixture { + final transport = MockTransport(); + final options = defaultTestOptions(); + + SentryClient getSut({bool attachStacktrace = true}) { + options.attachStacktrace = attachStacktrace; + options.transport = transport; + return SentryClient(options); + } +} +``` + +- Define `Fixture` at the bottom of each test file +- Use `getSut()` method to create the System Under Test with configurable options +- Initialize fixture in `setUp()` for each test group; when setup steps are shared use the top-most shared group to set up the fixture + +## Test Options + +Always use `defaultTestOptions()` from `test_utils.dart` to create options From 13b8895d6776ade144c4efedc527faa7f680a0e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:11:31 +0100 Subject: [PATCH 07/62] build(deps): bump aws-sdk-s3 from 1.203.0 to 1.208.0 in /metrics (#3428) Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.203.0 to 1.208.0. - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-ruby/commits) --- updated-dependencies: - dependency-name: aws-sdk-s3 dependency-version: 1.208.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- metrics/Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/metrics/Gemfile.lock b/metrics/Gemfile.lock index b7486e84d0..aff4675061 100644 --- a/metrics/Gemfile.lock +++ b/metrics/Gemfile.lock @@ -11,8 +11,8 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1181.0) - aws-sdk-core (3.236.0) + aws-partitions (1.1199.0) + aws-sdk-core (3.240.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -20,10 +20,10 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.117.0) - aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-kms (1.118.0) + aws-sdk-core (~> 3, >= 3.239.1) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.203.0) + aws-sdk-s3 (1.208.0) aws-sdk-core (~> 3, >= 3.234.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) @@ -32,7 +32,7 @@ GEM babosa (1.0.4) base64 (0.3.0) benchmark (0.5.0) - bigdecimal (3.3.1) + bigdecimal (4.0.1) claide (1.1.0) colored (1.2) colored2 (3.1.2) From e3f3ea121df01db0952a6642cbfa77c2d3ae1eb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:12:05 +0100 Subject: [PATCH 08/62] build(deps): bump aws-sdk-s3 in /packages/flutter/example/ios (#3417) Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.203.0 to 1.208.0. - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-ruby/commits) --- updated-dependencies: - dependency-name: aws-sdk-s3 dependency-version: 1.208.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/flutter/example/ios/Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/flutter/example/ios/Gemfile.lock b/packages/flutter/example/ios/Gemfile.lock index b7486e84d0..c8972a8690 100644 --- a/packages/flutter/example/ios/Gemfile.lock +++ b/packages/flutter/example/ios/Gemfile.lock @@ -11,8 +11,8 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.4.0) - aws-partitions (1.1181.0) - aws-sdk-core (3.236.0) + aws-partitions (1.1196.0) + aws-sdk-core (3.240.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) @@ -20,10 +20,10 @@ GEM bigdecimal jmespath (~> 1, >= 1.6.1) logger - aws-sdk-kms (1.117.0) - aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-kms (1.118.0) + aws-sdk-core (~> 3, >= 3.239.1) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.203.0) + aws-sdk-s3 (1.208.0) aws-sdk-core (~> 3, >= 3.234.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) @@ -32,7 +32,7 @@ GEM babosa (1.0.4) base64 (0.3.0) benchmark (0.5.0) - bigdecimal (3.3.1) + bigdecimal (4.0.1) claide (1.1.0) colored (1.2) colored2 (3.1.2) From 9e2dc30787dd589173cdff94cdb0558dee053b83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:12:29 +0100 Subject: [PATCH 09/62] build(deps): bump ruby/setup-ruby from 1.268.0 to 1.278.0 (#3430) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.268.0 to 1.278.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/8aeb6ff8030dd539317f8e1769a044873b56ea71...4c24fa5ec04b2e79eb40571b1cee2a0d2b705771) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.278.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/min_version_test.yml | 2 +- .github/workflows/testflight.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/min_version_test.yml b/.github/workflows/min_version_test.yml index a902c247f2..107213128b 100644 --- a/.github/workflows/min_version_test.yml +++ b/.github/workflows/min_version_test.yml @@ -51,7 +51,7 @@ jobs: with: flutter-version: '3.24.0' - - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # pin@v1.268.0 + - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 with: ruby-version: '3.1.2' # https://github.com/flutter/flutter/issues/109385#issuecomment-1212614125 diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index ac47c1a305..dda3cc712d 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v5 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - run: xcodes select 16.3 - - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # pin@v1.268.0 + - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 with: ruby-version: '2.7.5' bundler-cache: true From ffb3feff427d1e427122c928ea33e691428bd7bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:15:30 +0100 Subject: [PATCH 10/62] chore: update scripts/update-symbol-collector.sh to 2.3.1 (#3385) Co-authored-by: GitHub --- .../flutter_symbol_collector/lib/src/symbol_collector_cli.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/flutter_symbol_collector/lib/src/symbol_collector_cli.dart b/scripts/flutter_symbol_collector/lib/src/symbol_collector_cli.dart index a13761fad6..395a30eda7 100644 --- a/scripts/flutter_symbol_collector/lib/src/symbol_collector_cli.dart +++ b/scripts/flutter_symbol_collector/lib/src/symbol_collector_cli.dart @@ -19,7 +19,7 @@ class SymbolCollectorCli { // https://github.com/getsentry/symbol-collector/releases @internal - static const version = '2.2.1'; + static const version = '2.3.1'; @internal late final String cli; From 55ba4de4e3d63bd07eddcc2200eb74e9a4cba3a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:17:42 +0100 Subject: [PATCH 11/62] build(deps): bump reactivecircus/android-emulator-runner (#3328) Bumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.34.0 to 2.35.0. - [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases) - [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md) - [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/1dcd0090116d15e7c562f8db72807de5e036a4ed...b530d96654c385303d652368551fb075bc2f0b6b) --- updated-dependencies: - dependency-name: reactivecircus/android-emulator-runner dependency-version: 2.35.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Giancarlo Buenaflor --- .github/workflows/flutter_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter_test.yml b/.github/workflows/flutter_test.yml index 0b8889dcf4..79e0693058 100644 --- a/.github/workflows/flutter_test.yml +++ b/.github/workflows/flutter_test.yml @@ -57,7 +57,7 @@ jobs: # TODO: fix emulator caching, in ubuntu-latest emulator won't boot: https://github.com/ReactiveCircus/android-emulator-runner/issues/278 - name: Launch Android emulator & run Flutter Android integration test - uses: reactivecircus/android-emulator-runner@1dcd0090116d15e7c562f8db72807de5e036a4ed #pin@v2.34.0 + uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b #pin@v2.35.0 with: working-directory: packages/flutter/example api-level: 31 From e5ae2a6fea902141635625ef10a5ad4040a416f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 11:51:12 +0100 Subject: [PATCH 12/62] chore: update metrics/flutter.properties to 3.38.5 (#3387) Co-authored-by: GitHub --- metrics/flutter.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/flutter.properties b/metrics/flutter.properties index f1335e1723..87e880bdc2 100644 --- a/metrics/flutter.properties +++ b/metrics/flutter.properties @@ -1,2 +1,2 @@ -version = 3.35.5 +version = 3.38.5 repo = https://github.com/flutter/flutter From dc53d4895daad93a21f4d51721339399d956af0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 13:38:05 +0100 Subject: [PATCH 13/62] build(deps): bump actions/checkout from 4 to 6 (#3365) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Giancarlo Buenaflor --- .github/workflows/analyze.yml | 4 ++-- .github/workflows/changes-in-high-risk-code.yml | 2 +- .github/workflows/dart.yml | 2 +- .github/workflows/diagrams.yml | 2 +- .github/workflows/dio.yml | 2 +- .github/workflows/drift.yml | 2 +- .github/workflows/e2e_dart.yml | 2 +- .github/workflows/file.yml | 2 +- .github/workflows/firebase_remote_config.yml | 2 +- .github/workflows/flutter-symbols.yml | 4 ++-- .github/workflows/flutter.yml | 12 ++++++------ .github/workflows/flutter_test.yml | 6 +++--- .github/workflows/format-and-fix.yml | 2 +- .github/workflows/hive.yml | 2 +- .github/workflows/isar.yml | 2 +- .github/workflows/link.yml | 2 +- .github/workflows/logging.yml | 2 +- .github/workflows/metrics.yml | 4 ++-- .github/workflows/min_version_test.yml | 6 +++--- .github/workflows/release.yml | 2 +- .github/workflows/sqflite.yml | 2 +- .github/workflows/supabase.yml | 2 +- .github/workflows/testflight.yml | 2 +- .github/workflows/web-example-ghpages.yml | 2 +- 24 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index b60aae5f5f..dfaaed3e0a 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -23,7 +23,7 @@ jobs: run: working-directory: ${{ inputs.package }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # pin@v1 if: ${{ inputs.sdk == 'dart' }} - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 @@ -60,7 +60,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Apply dependency override if: ${{ inputs.package == 'flutter' }} working-directory: ${{ inputs.package }} diff --git a/.github/workflows/changes-in-high-risk-code.yml b/.github/workflows/changes-in-high-risk-code.yml index 8522c96c33..70771ad90e 100644 --- a/.github/workflows/changes-in-high-risk-code.yml +++ b/.github/workflows/changes-in-high-risk-code.yml @@ -15,7 +15,7 @@ jobs: high_risk_code: ${{ steps.changes.outputs.high_risk_code }} high_risk_code_files: ${{ steps.changes.outputs.high_risk_code_files }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Get changed files id: changes uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 0343409e75..77ab731a8f 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -37,7 +37,7 @@ jobs: - os: macos sdk: stable steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/diagrams.yml b/.github/workflows/diagrams.yml index 1ce9a07c7e..f13acc7c09 100644 --- a/.github/workflows/diagrams.yml +++ b/.github/workflows/diagrams.yml @@ -11,7 +11,7 @@ jobs: with: sdk: stable - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: dependencies run: | diff --git a/.github/workflows/dio.yml b/.github/workflows/dio.yml index 0b5e614306..6ad7e24f4b 100644 --- a/.github/workflows/dio.yml +++ b/.github/workflows/dio.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/drift.yml b/.github/workflows/drift.yml index 9258efa3e8..18ea1c832a 100644 --- a/.github/workflows/drift.yml +++ b/.github/workflows/drift.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Install libsqlite3 (Ubuntu) if: matrix.os == 'ubuntu' diff --git a/.github/workflows/e2e_dart.yml b/.github/workflows/e2e_dart.yml index 9924215203..756273bb43 100644 --- a/.github/workflows/e2e_dart.yml +++ b/.github/workflows/e2e_dart.yml @@ -37,7 +37,7 @@ jobs: - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # pin@v1 with: sdk: ${{ matrix.sdk }} - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Run if: env.SENTRY_AUTH_TOKEN != null run: | diff --git a/.github/workflows/file.yml b/.github/workflows/file.yml index 99f1a449e4..51e98f02b3 100644 --- a/.github/workflows/file.yml +++ b/.github/workflows/file.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/firebase_remote_config.yml b/.github/workflows/firebase_remote_config.yml index eb2c9279ac..0c24fb0ad3 100644 --- a/.github/workflows/firebase_remote_config.yml +++ b/.github/workflows/firebase_remote_config.yml @@ -32,7 +32,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/flutter-test with: diff --git a/.github/workflows/flutter-symbols.yml b/.github/workflows/flutter-symbols.yml index 4b176f92da..539e916af3 100644 --- a/.github/workflows/flutter-symbols.yml +++ b/.github/workflows/flutter-symbols.yml @@ -19,7 +19,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # pin@v1 @@ -31,7 +31,7 @@ jobs: needs: [test] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # pin@v1 diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index f51479a744..91cf1c1b5b 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -53,7 +53,7 @@ jobs: sdk: beta steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/flutter-test with: @@ -118,7 +118,7 @@ jobs: target: [ios, macos] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 with: @@ -152,7 +152,7 @@ jobs: run: working-directory: packages/flutter steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # https://github.com/CocoaPods/CocoaPods/issues/5275#issuecomment-315461879 # QuickFix for failing iOS 18.0 builds https://github.com/actions/runner-images/issues/12758#issuecomment-3187115656 @@ -168,7 +168,7 @@ jobs: run: working-directory: packages/flutter steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: norio-nomura/action-swiftlint@9f4dcd7fd46b4e75d7935cf2f4df406d5cae3684 # pin@3.2.1 with: args: --strict @@ -180,7 +180,7 @@ jobs: run: working-directory: packages/flutter steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: ktlint uses: ScaCap/action-ktlint@26c5e9b625966139d9956cbbb6217375480d4e14 # pin@1.9.0 @@ -195,7 +195,7 @@ jobs: # runs-on: ubuntu-latest # timeout-minutes: 20 # steps: -# - uses: actions/checkout@v5 +# - uses: actions/checkout@v6 # # To recreate baseline run: detekt -i packages/flutter/android,packages/flutter/example/android -b packages/flutter/config/detekt-bl.xml -cb # - uses: natiginfo/action-detekt-all@45229fbbe47eaff1160b6c956d7ffe14dc23c206 # pin@1.23.8 # with: diff --git a/.github/workflows/flutter_test.yml b/.github/workflows/flutter_test.yml index 79e0693058..3ed94346e0 100644 --- a/.github/workflows/flutter_test.yml +++ b/.github/workflows/flutter_test.yml @@ -32,7 +32,7 @@ jobs: sdk: [stable, beta] steps: - name: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Enable KVM group perms run: | @@ -91,7 +91,7 @@ jobs: sdk: [stable] steps: - name: checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 with: @@ -158,7 +158,7 @@ jobs: # sdk: ['stable'] # steps: # - name: checkout -# uses: actions/checkout@v5 +# uses: actions/checkout@v6 # # - name: Install Chrome Browser # uses: browser-actions/setup-chrome@b94431e051d1c52dcbe9a7092a4f10f827795416 # pin@v2.1.0 diff --git a/.github/workflows/format-and-fix.yml b/.github/workflows/format-and-fix.yml index a9aede7508..90f61b9443 100644 --- a/.github/workflows/format-and-fix.yml +++ b/.github/workflows/format-and-fix.yml @@ -26,7 +26,7 @@ jobs: run: working-directory: ${{ matrix.package.name }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # pin@v1 if: ${{ matrix.package.sdk == 'dart' }} - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index 94f58775f6..3e99e15d25 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/isar.yml b/.github/workflows/isar.yml index 809547df5d..da37bf9b36 100644 --- a/.github/workflows/isar.yml +++ b/.github/workflows/isar.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/flutter-test with: diff --git a/.github/workflows/link.yml b/.github/workflows/link.yml index 32858890aa..65dd36f0b2 100644 --- a/.github/workflows/link.yml +++ b/.github/workflows/link.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/logging.yml b/.github/workflows/logging.yml index 50a755c700..659b8295d4 100644 --- a/.github/workflows/logging.yml +++ b/.github/workflows/logging.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: ./.github/actions/dart-test with: diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml index bd23cd29a6..57c293eec3 100644 --- a/.github/workflows/metrics.yml +++ b/.github/workflows/metrics.yml @@ -37,7 +37,7 @@ jobs: host: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # Let's stick to an explicit version and update manually because a version change may affect results. # If it would update implicitly it could confuse people to think the change is actually caused by the PR. @@ -97,7 +97,7 @@ jobs: name: Console runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - name: create dart sample apps diff --git a/.github/workflows/min_version_test.yml b/.github/workflows/min_version_test.yml index 107213128b..399ba4b732 100644 --- a/.github/workflows/min_version_test.yml +++ b/.github/workflows/min_version_test.yml @@ -23,7 +23,7 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: @@ -45,7 +45,7 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 with: @@ -80,7 +80,7 @@ jobs: timeout-minutes: 30 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc51e593fd..258b43726e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} - name: Check out current commit (${{ github.sha }}) - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: token: ${{ steps.token.outputs.token }} fetch-depth: 0 diff --git a/.github/workflows/sqflite.yml b/.github/workflows/sqflite.yml index f573c46c0a..52a8424756 100644 --- a/.github/workflows/sqflite.yml +++ b/.github/workflows/sqflite.yml @@ -31,7 +31,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Install libsqlite3 if: matrix.target == 'linux' diff --git a/.github/workflows/supabase.yml b/.github/workflows/supabase.yml index 1405d32451..0432960682 100644 --- a/.github/workflows/supabase.yml +++ b/.github/workflows/supabase.yml @@ -33,7 +33,7 @@ jobs: sdk: [stable, beta] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ./.github/actions/flutter-test with: diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index dda3cc712d..c3190687d6 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -14,7 +14,7 @@ jobs: name: Build and Upload to Testflight runs-on: macos-15 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - run: xcodes select 16.3 - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 diff --git a/.github/workflows/web-example-ghpages.yml b/.github/workflows/web-example-ghpages.yml index d5701c1bbd..1fcb09ee44 100644 --- a/.github/workflows/web-example-ghpages.yml +++ b/.github/workflows/web-example-ghpages.yml @@ -13,7 +13,7 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - uses: bluefireteam/flutter-gh-pages@cf4a9312849577dbfd9df8f3d63d12ef6b09898e # pin@v9 with: From 2f63d89815a4c91f192456a65182e4e672e45c86 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 22:23:55 +0100 Subject: [PATCH 14/62] chore: update packages/flutter/scripts/update-native.sh to 0.12.3 (#3438) Co-authored-by: GitHub --- CHANGELOG.md | 8 ++ .../flutter/lib/src/native/c/binding.dart | 92 +++++++++---------- packages/flutter/sentry-native/CMakeCache.txt | 2 +- 3 files changed, 50 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4e4870171..7d8bc0255d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Dependencies + +- Bump Native SDK from v0.10.0 to v0.12.3 ([#3438](https://github.com/getsentry/sentry-dart/pull/3438)) + - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0123) + - [diff](https://github.com/getsentry/sentry-native/compare/0.10.0...0.12.3) + ## 9.9.2 ### Fixes diff --git a/packages/flutter/lib/src/native/c/binding.dart b/packages/flutter/lib/src/native/c/binding.dart index 9b10e2ff76..ec6ce08d59 100644 --- a/packages/flutter/lib/src/native/c/binding.dart +++ b/packages/flutter/lib/src/native/c/binding.dart @@ -131,16 +131,16 @@ class SentryNative { _value_new_objectPtr.asFunction(); /// Returns the type of the value passed. - sentry_value_type_t value_get_type( + int value_get_type( sentry_value_u value, ) { - return sentry_value_type_t.fromValue(_value_get_type( + return _value_get_type( value, - )); + ); } late final _value_get_typePtr = - _lookup>( + _lookup>( 'sentry_value_get_type'); late final _value_get_type = _value_get_typePtr.asFunction(); @@ -206,7 +206,7 @@ class SentryNative { late final _value_append = _value_appendPtr .asFunction(); - /// Looks up a value in a map by key. If missing a null value is returned. + /// Looks up a value in a map by key. If missing, a null value is returned. /// The returned value is borrowed. sentry_value_u value_get_by_key( sentry_value_u value, @@ -225,7 +225,7 @@ class SentryNative { late final _value_get_by_key = _value_get_by_keyPtr.asFunction< sentry_value_u Function(sentry_value_u, ffi.Pointer)>(); - /// Looks up a value in a list by index. If missing a null value is returned. + /// Looks up a value in a list by index. If missing, a null value is returned. /// The returned value is borrowed. sentry_value_u value_get_by_index( sentry_value_u value, @@ -246,7 +246,7 @@ class SentryNative { /// Returns the length of the given map or list. /// - /// If an item is not a list or map the return value is 0. + /// If an item is not a list or map, the return value is 0. int value_get_length( sentry_value_u value, ) { @@ -612,8 +612,15 @@ class SentryNative { /// Sets the path to the crashpad handler if the crashpad backend is used. /// /// The path defaults to the `crashpad_handler`/`crashpad_handler.exe` - /// executable, depending on platform, which is expected to be present in the - /// same directory as the app executable. + /// executable in the same directory as the application executable. + /// + /// Meaning if your application resides in + /// + /// "C:\path\to\your\application.exe" + /// + /// then the handler path will be set (by default) to + /// + /// "C:\path\to\your\crashpad_handler.exe" /// /// It is recommended that library users set an explicit handler path, depending /// on the directory/executable structure of their app. @@ -656,15 +663,15 @@ class SentryNative { /// /// It is recommended that users set an explicit absolute path, depending /// on their apps runtime directory. The path will be created if it does not - /// exist, and will be resolved to an absolute path inside of `sentry_init`. The + /// exist and will be resolved to an absolute path inside `sentry_init`. The /// directory should not be shared with other application data/configuration, as - /// sentry-native will enumerate and possibly delete files in that directory. An + /// sentry-native will list and possibly delete files in that directory. An /// example might be `$XDG_CACHE_HOME/your-app/sentry` /// - /// If no explicit path it set, sentry-native will default to `.sentry-native` in + /// If no explicit path is set, sentry-native will default to `.sentry-native` in /// the current working directory, with no specific platform-specific handling. /// - /// `path` is assumed to be in platform-specific filesystem path encoding. + /// `path` is assumed to be in a platform-specific filesystem path encoding. /// API Users on windows are encouraged to use /// `sentry_options_set_database_pathw` instead. void options_set_database_path( @@ -688,8 +695,8 @@ class SentryNative { /// Initializes the Sentry SDK with the specified options. /// - /// This takes ownership of the options. After the options have been set - /// they cannot be modified any more. + /// This takes ownership of the options. After the options have been set, + /// they cannot be modified anymore. /// Depending on the configured transport and backend, this function might not be /// fully thread-safe. /// Returns 0 on success. @@ -709,14 +716,14 @@ class SentryNative { /// Shuts down the sentry client and forces transports to flush out. /// - /// Returns 0 on success. + /// Returns the number of envelopes that have been dumped. /// /// Note that this does not uninstall any crash handler installed by our /// backends, which will still process crashes after `sentry_close()`, except /// when using `crashpad` on Linux or the `inproc` backend. /// /// Further note that this function will block the thread it was called from - /// until the sentry background worker has finished its work or it timed out, + /// until the sentry background worker has finished its work, or it timed out, /// whichever comes first. int close() { return _close(); @@ -901,48 +908,18 @@ class SentryNative { _sdk_namePtr.asFunction Function()>(); } -/// Type of a sentry value. -enum sentry_value_type_t { - SENTRY_VALUE_TYPE_NULL(0), - SENTRY_VALUE_TYPE_BOOL(1), - SENTRY_VALUE_TYPE_INT32(2), - SENTRY_VALUE_TYPE_INT64(3), - SENTRY_VALUE_TYPE_UINT64(4), - SENTRY_VALUE_TYPE_DOUBLE(5), - SENTRY_VALUE_TYPE_STRING(6), - SENTRY_VALUE_TYPE_LIST(7), - SENTRY_VALUE_TYPE_OBJECT(8); - - final int value; - const sentry_value_type_t(this.value); - - static sentry_value_type_t fromValue(int value) => switch (value) { - 0 => SENTRY_VALUE_TYPE_NULL, - 1 => SENTRY_VALUE_TYPE_BOOL, - 2 => SENTRY_VALUE_TYPE_INT32, - 3 => SENTRY_VALUE_TYPE_INT64, - 4 => SENTRY_VALUE_TYPE_UINT64, - 5 => SENTRY_VALUE_TYPE_DOUBLE, - 6 => SENTRY_VALUE_TYPE_STRING, - 7 => SENTRY_VALUE_TYPE_LIST, - 8 => SENTRY_VALUE_TYPE_OBJECT, - _ => - throw ArgumentError('Unknown value for sentry_value_type_t: $value'), - }; -} - /// Represents a sentry protocol value. /// /// The members of this type should never be accessed. They are only here /// so that alignment for the type can be properly determined. /// /// Values must be released with `sentry_value_decref`. This lowers the -/// internal refcount by one. If the refcount hits zero it's freed. Some -/// values like primitives have no refcount (like null) so operations on +/// internal refcount by one. If the refcount hits zero, it's freed. Some +/// values like primitives have no refcount (like null), so operations on /// those are no-ops. /// -/// In addition values can be frozen. Some values like primitives are always -/// frozen but lists and dicts are not and can be frozen on demand. This +/// In addition, values can be frozen. Some values like primitives are always +/// frozen, but lists and dicts are not and can be frozen on demand. This /// automatically happens for some shared values in the event payload like /// the module list. final class sentry_value_u extends ffi.Union { @@ -953,6 +930,19 @@ final class sentry_value_u extends ffi.Union { external double _double; } +/// Type of sentry value. +abstract class sentry_value_type_t { + static const int SENTRY_VALUE_TYPE_NULL = 0; + static const int SENTRY_VALUE_TYPE_BOOL = 1; + static const int SENTRY_VALUE_TYPE_INT32 = 2; + static const int SENTRY_VALUE_TYPE_INT64 = 3; + static const int SENTRY_VALUE_TYPE_UINT64 = 4; + static const int SENTRY_VALUE_TYPE_DOUBLE = 5; + static const int SENTRY_VALUE_TYPE_STRING = 6; + static const int SENTRY_VALUE_TYPE_LIST = 7; + static const int SENTRY_VALUE_TYPE_OBJECT = 8; +} + /// The Sentry Client Options. /// /// See https://docs.sentry.io/platforms/native/configuration/ diff --git a/packages/flutter/sentry-native/CMakeCache.txt b/packages/flutter/sentry-native/CMakeCache.txt index ec828fe479..dba0a16109 100644 --- a/packages/flutter/sentry-native/CMakeCache.txt +++ b/packages/flutter/sentry-native/CMakeCache.txt @@ -2,4 +2,4 @@ # Basically, this is a properties file we use both in CMake and update-deps.yml to update dependencies. repo=https://github.com/getsentry/sentry-native -version=0.10.0 +version=0.12.3 From 1661d6771a3798009128155a9ef736d71e043d23 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Tue, 13 Jan 2026 15:20:20 +0100 Subject: [PATCH 15/62] Add claude settings (#3445) --- .claude/settings.json | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000000..8767f3b4e2 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,79 @@ +{ + "permissions": { + "allow": [ + "Bash(ls:*)", + "Bash(pwd:*)", + "Bash(find:*)", + "Bash(file:*)", + "Bash(stat:*)", + "Bash(wc:*)", + "Bash(head:*)", + "Bash(tail:*)", + "Bash(cat:*)", + "Bash(tree:*)", + + "Bash(git status:*)", + "Bash(git log:*)", + "Bash(git diff:*)", + "Bash(git show:*)", + "Bash(git branch:*)", + "Bash(git remote:*)", + "Bash(git tag:*)", + "Bash(git stash list:*)", + "Bash(git rev-parse:*)", + "Bash(git fetch:*)", + "Bash(git ls-files:*)", + "Bash(git blame:*)", + + "Bash(gh pr view:*)", + "Bash(gh pr list:*)", + "Bash(gh pr checks:*)", + "Bash(gh pr diff:*)", + "Bash(gh issue view:*)", + "Bash(gh issue list:*)", + "Bash(gh run view:*)", + "Bash(gh run list:*)", + "Bash(gh run logs:*)", + "Bash(gh repo view:*)", + "Bash(gh api:*)", + + "WebFetch(domain:docs.sentry.io)", + "WebFetch(domain:develop.sentry.dev)", + "WebFetch(domain:docs.github.com)", + "WebFetch(domain:cli.github.com)", + + "Skill(sentry-skills:commit)", + "Skill(sentry-skills:create-pr)", + "Skill(sentry-skills:deslop)", + "Skill(sentry-skills:iterate-pr)", + "Skill(sentry-skills:claude-settings-audit)", + "Skill(sentry-skills:agents-md)", + + "Bash(fvm --version:*)", + "Bash(fvm list:*)", + "Bash(fvm releases:*)", + "Bash(fvm config:*)", + "Bash(fvm flutter --version:*)", + "Bash(fvm dart --version:*)", + + "Bash(fvm flutter pub get:*)", + "Bash(fvm flutter pub deps:*)", + "Bash(fvm flutter pub outdated:*)", + "Bash(fvm flutter pub cache repair:*)", + + "Bash(fvm flutter analyze:*)", + "Bash(fvm dart analyze:*)", + "Bash(fvm dart format:*)", + "Bash(fvm dart fix:*)", + "Bash(fvm flutter test:*)", + "Bash(fvm dart test:*)", + + "Bash(fvm flutter devices:*)", + "Bash(fvm flutter emulators:*)", + "Bash(fvm flutter run:*)", + "Bash(fvm flutter build *:*)", + "Bash(fvm flutter doctor:*)" + ], + "deny": [] + } +} \ No newline at end of file From 9821ba4ad87b0b932ce1f9af9063ca7f5cc92f5d Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Tue, 13 Jan 2026 15:24:04 +0100 Subject: [PATCH 16/62] Add `CLAUDE.md` symlink to `AGENTS.md` --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) create mode 120000 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000000..47dc3e3d86 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file From c002f0063984c486ae09ae29da251b9ee724fd07 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 15 Jan 2026 14:29:35 +0100 Subject: [PATCH 17/62] Move `TelemetryProcessor` from span-first branch and replace `LogBatcher` (#3448) * Add TelemetryProcessor for span and log buffering Co-Authored-By: Claude Sonnet 4.5 * Remove SpanV2 and TraceLifecycle dependencies - Remove addSpan method from TelemetryProcessor interface - Remove span buffer from DefaultTelemetryProcessor - Remove captureSpan method from SentryClient - Remove traceLifecycle property from SentryOptions - Remove span imports and exports - Update mocks to remove span-related code Co-Authored-By: Claude Sonnet 4.5 * Remove span-related tests from sentry_client_test Co-Authored-By: Claude Sonnet 4.5 * Remove span-related processor tests Co-Authored-By: Claude Sonnet 4.5 * Remove span import from Flutter mocks Co-Authored-By: Claude Sonnet 4.5 * Fix wiring up * Update * Update * Update CHANGELOG * Update * Remove logbatcher * Polish --------- Co-authored-by: Claude Sonnet 4.5 --- CHANGELOG.md | 4 + packages/dart/lib/src/noop_log_batcher.dart | 12 -- packages/dart/lib/src/sentry.dart | 2 + packages/dart/lib/src/sentry_client.dart | 8 +- packages/dart/lib/src/sentry_log_batcher.dart | 94 -------- packages/dart/lib/src/sentry_options.dart | 5 +- .../lib/src/telemetry/processing/buffer.dart | 13 ++ .../telemetry/processing/buffer_config.dart | 15 ++ .../processing/in_memory_buffer.dart | 143 +++++++++++++ .../src/telemetry/processing/processor.dart | 72 +++++++ .../processing/processor_integration.dart | 37 ++++ .../dart/test/mocks/mock_log_batcher.dart | 19 -- .../test/mocks/mock_telemetry_buffer.dart | 23 ++ .../test/mocks/mock_telemetry_processor.dart | 18 ++ .../test/sentry_client_lifecycle_test.dart | 13 +- .../sentry_client_sdk_lifecycle_test.dart | 13 +- packages/dart/test/sentry_client_test.dart | 123 +++++------ .../dart/test/sentry_log_batcher_test.dart | 149 ------------- packages/dart/test/sentry_test.dart | 22 ++ .../telemetry/processing/buffer_test.dart | 201 ++++++++++++++++++ .../processor_integration_test.dart | 96 +++++++++ .../telemetry/processing/processor_test.dart | 100 +++++++++ .../lib/src/widgets_binding_observer.dart | 2 +- packages/flutter/test/mocks.dart | 17 ++ .../test/widgets_binding_observer_test.dart | 23 +- 25 files changed, 839 insertions(+), 385 deletions(-) delete mode 100644 packages/dart/lib/src/noop_log_batcher.dart delete mode 100644 packages/dart/lib/src/sentry_log_batcher.dart create mode 100644 packages/dart/lib/src/telemetry/processing/buffer.dart create mode 100644 packages/dart/lib/src/telemetry/processing/buffer_config.dart create mode 100644 packages/dart/lib/src/telemetry/processing/in_memory_buffer.dart create mode 100644 packages/dart/lib/src/telemetry/processing/processor.dart create mode 100644 packages/dart/lib/src/telemetry/processing/processor_integration.dart delete mode 100644 packages/dart/test/mocks/mock_log_batcher.dart create mode 100644 packages/dart/test/mocks/mock_telemetry_buffer.dart create mode 100644 packages/dart/test/mocks/mock_telemetry_processor.dart delete mode 100644 packages/dart/test/sentry_log_batcher_test.dart create mode 100644 packages/dart/test/telemetry/processing/buffer_test.dart create mode 100644 packages/dart/test/telemetry/processing/processor_integration_test.dart create mode 100644 packages/dart/test/telemetry/processing/processor_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d8bc0255d..e06a63c8d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Replace log batcher with telemetry processor ([#3448](https://github.com/getsentry/sentry-dart/pull/3448)) + ### Dependencies - Bump Native SDK from v0.10.0 to v0.12.3 ([#3438](https://github.com/getsentry/sentry-dart/pull/3438)) diff --git a/packages/dart/lib/src/noop_log_batcher.dart b/packages/dart/lib/src/noop_log_batcher.dart deleted file mode 100644 index 52242b62a5..0000000000 --- a/packages/dart/lib/src/noop_log_batcher.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:async'; - -import 'sentry_log_batcher.dart'; -import 'protocol/sentry_log.dart'; - -class NoopLogBatcher implements SentryLogBatcher { - @override - FutureOr addLog(SentryLog log) {} - - @override - FutureOr flush() {} -} diff --git a/packages/dart/lib/src/sentry.dart b/packages/dart/lib/src/sentry.dart index f65bc721b1..2ea7824950 100644 --- a/packages/dart/lib/src/sentry.dart +++ b/packages/dart/lib/src/sentry.dart @@ -23,6 +23,7 @@ import 'sentry_attachment/sentry_attachment.dart'; import 'sentry_client.dart'; import 'sentry_options.dart'; import 'sentry_run_zoned_guarded.dart'; +import 'telemetry/processing/processor_integration.dart'; import 'tracing.dart'; import 'transport/data_category.dart'; import 'transport/task_queue.dart'; @@ -111,6 +112,7 @@ class Sentry { options.addIntegration(FeatureFlagsIntegration()); options.addIntegration(LogsEnricherIntegration()); + options.addIntegration(InMemoryTelemetryProcessorIntegration()); options.addEventProcessor(EnricherEventProcessor(options)); options.addEventProcessor(ExceptionEventProcessor(options)); diff --git a/packages/dart/lib/src/sentry_client.dart b/packages/dart/lib/src/sentry_client.dart index b53eb998ac..02e6841e1d 100644 --- a/packages/dart/lib/src/sentry_client.dart +++ b/packages/dart/lib/src/sentry_client.dart @@ -28,7 +28,6 @@ import 'type_check_hint.dart'; import 'utils/isolate_utils.dart'; import 'utils/regex_utils.dart'; import 'utils/stacktrace_utils.dart'; -import 'sentry_log_batcher.dart'; import 'version.dart'; /// Default value for [SentryUser.ipAddress]. It gets set when an event does not have @@ -75,9 +74,6 @@ class SentryClient { if (enableFlutterSpotlight) { options.transport = SpotlightHttpTransport(options, options.transport); } - if (options.enableLogs) { - options.logBatcher = SentryLogBatcher(options); - } return SentryClient._(options); } @@ -578,7 +574,7 @@ class SentryClient { if (processedLog != null) { await _options.lifecycleRegistry .dispatchCallback(OnBeforeCaptureLog(processedLog)); - _options.logBatcher.addLog(processedLog); + _options.telemetryProcessor.addLog(processedLog); } else { _options.recorder.recordLostEvent( DiscardReason.beforeSend, @@ -588,7 +584,7 @@ class SentryClient { } FutureOr close() { - final flush = _options.logBatcher.flush(); + final flush = _options.telemetryProcessor.flush(); if (flush is Future) { return flush.then((_) => _options.httpClient.close()); } diff --git a/packages/dart/lib/src/sentry_log_batcher.dart b/packages/dart/lib/src/sentry_log_batcher.dart deleted file mode 100644 index 4c5867fc16..0000000000 --- a/packages/dart/lib/src/sentry_log_batcher.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:async'; -import 'sentry_options.dart'; -import 'protocol/sentry_log.dart'; -import 'protocol/sentry_level.dart'; -import 'sentry_envelope.dart'; -import 'utils.dart'; -import 'package:meta/meta.dart'; - -@internal -class SentryLogBatcher { - SentryLogBatcher( - this._options, { - Duration? flushTimeout, - int? maxBufferSizeBytes, - }) : _flushTimeout = flushTimeout ?? Duration(seconds: 5), - _maxBufferSizeBytes = maxBufferSizeBytes ?? - 1024 * 1024; // 1MB default per BatchProcessor spec - - final SentryOptions _options; - final Duration _flushTimeout; - final int _maxBufferSizeBytes; - - // Store encoded log data instead of raw logs to avoid re-serialization - final List> _encodedLogs = []; - int _encodedLogsSize = 0; - - Timer? _flushTimer; - - /// Adds a log to the buffer. - void addLog(SentryLog log) { - try { - final encodedLog = utf8JsonEncoder.convert(log.toJson()); - - _encodedLogs.add(encodedLog); - _encodedLogsSize += encodedLog.length; - - // Flush if size threshold is reached - if (_encodedLogsSize >= _maxBufferSizeBytes) { - // Buffer size exceeded, flush immediately - _performFlushLogs(); - } else if (_flushTimer == null) { - // Start timeout only when first item is added - _startTimer(); - } - // Note: We don't restart the timer on subsequent additions per spec - } catch (error) { - _options.log( - SentryLevel.error, - 'Failed to encode log: $error', - ); - } - } - - /// Flushes the buffer immediately, sending all buffered logs. - FutureOr flush() => _performFlushLogs(); - - void _startTimer() { - _flushTimer = Timer(_flushTimeout, () { - _options.log( - SentryLevel.debug, - 'SentryLogBatcher: Timer fired, calling performCaptureLogs().', - ); - _performFlushLogs(); - }); - } - - FutureOr _performFlushLogs() { - // Reset timer state first - _flushTimer?.cancel(); - _flushTimer = null; - - // Reset buffer on function exit - final logsToSend = List>.from(_encodedLogs); - _encodedLogs.clear(); - _encodedLogsSize = 0; - - if (logsToSend.isEmpty) { - _options.log( - SentryLevel.debug, - 'SentryLogBatcher: No logs to flush.', - ); - } else { - try { - final envelope = SentryEnvelope.fromLogsData(logsToSend, _options.sdk); - return _options.transport.send(envelope).then((_) => null); - } catch (error) { - _options.log( - SentryLevel.error, - 'Failed to create envelope for batched logs: $error', - ); - } - } - } -} diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index 9cb8b881fa..f0b7472f3e 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -12,10 +12,9 @@ import 'noop_client.dart'; import 'platform/platform.dart'; import 'sentry_exception_factory.dart'; import 'sentry_stack_trace_factory.dart'; +import 'telemetry/processing/processor.dart'; import 'transport/noop_transport.dart'; import 'version.dart'; -import 'sentry_log_batcher.dart'; -import 'noop_log_batcher.dart'; import 'dart:developer' as developer; // TODO: shutdownTimeout, flushTimeoutMillis @@ -554,7 +553,7 @@ class SentryOptions { late final SentryLogger logger = SentryLogger(clock); @internal - SentryLogBatcher logBatcher = NoopLogBatcher(); + TelemetryProcessor telemetryProcessor = NoOpTelemetryProcessor(); SentryOptions({String? dsn, Platform? platform, RuntimeChecker? checker}) { this.dsn = dsn; diff --git a/packages/dart/lib/src/telemetry/processing/buffer.dart b/packages/dart/lib/src/telemetry/processing/buffer.dart new file mode 100644 index 0000000000..518c9808ad --- /dev/null +++ b/packages/dart/lib/src/telemetry/processing/buffer.dart @@ -0,0 +1,13 @@ +import 'dart:async'; + +/// A buffer that batches telemetry items for efficient transmission to Sentry. +/// +/// Collects items of type [T] and sends them in batches rather than +/// individually, reducing network overhead. +abstract class TelemetryBuffer { + /// Adds an item to the buffer. + void add(T item); + + /// When executed immediately sends all buffered items to Sentry and clears the buffer. + FutureOr flush(); +} diff --git a/packages/dart/lib/src/telemetry/processing/buffer_config.dart b/packages/dart/lib/src/telemetry/processing/buffer_config.dart new file mode 100644 index 0000000000..7ef8214aa1 --- /dev/null +++ b/packages/dart/lib/src/telemetry/processing/buffer_config.dart @@ -0,0 +1,15 @@ +final class TelemetryBufferConfig { + final Duration flushTimeout; + final int maxBufferSizeBytes; + final int maxItemCount; + + const TelemetryBufferConfig({ + this.flushTimeout = defaultFlushTimeout, + this.maxBufferSizeBytes = defaultMaxBufferSizeBytes, + this.maxItemCount = defaultMaxItemCount, + }); + + static const Duration defaultFlushTimeout = Duration(seconds: 5); + static const int defaultMaxBufferSizeBytes = 1024 * 1024; + static const int defaultMaxItemCount = 100; +} diff --git a/packages/dart/lib/src/telemetry/processing/in_memory_buffer.dart b/packages/dart/lib/src/telemetry/processing/in_memory_buffer.dart new file mode 100644 index 0000000000..be97f5f0a4 --- /dev/null +++ b/packages/dart/lib/src/telemetry/processing/in_memory_buffer.dart @@ -0,0 +1,143 @@ +import 'dart:async'; + +import '../../utils/internal_logger.dart'; +import 'buffer.dart'; +import 'buffer_config.dart'; + +/// Callback invoked when the buffer is flushed with the accumulated data. +typedef OnFlushCallback = FutureOr Function(T data); + +/// Encodes an item of type [T] into bytes. +typedef ItemEncoder = List Function(T item); + +/// Base class for in-memory telemetry buffers. +/// +/// Buffers telemetry items in memory and flushes them when either the +/// configured size limit, item count limit, or flush timeout is reached. +abstract base class _BaseInMemoryTelemetryBuffer + implements TelemetryBuffer { + final TelemetryBufferConfig _config; + final ItemEncoder _encoder; + final OnFlushCallback _onFlush; + + S _storage; + int _bufferSize = 0; + int _itemCount = 0; + Timer? _flushTimer; + + _BaseInMemoryTelemetryBuffer({ + required ItemEncoder encoder, + required OnFlushCallback onFlush, + required S initialStorage, + TelemetryBufferConfig config = const TelemetryBufferConfig(), + }) : _encoder = encoder, + _onFlush = onFlush, + _storage = initialStorage, + _config = config; + + S _createEmptyStorage(); + void _store(List encoded, T item); + bool get _isEmpty; + + bool get _isBufferFull => + _bufferSize >= _config.maxBufferSizeBytes || + _itemCount >= _config.maxItemCount; + + @override + void add(T item) { + final List encoded; + try { + encoded = _encoder(item); + } catch (exception, stackTrace) { + internalLogger.error( + '$runtimeType: Failed to encode item, dropping', + error: exception, + stackTrace: stackTrace, + ); + return; + } + + if (encoded.length > _config.maxBufferSizeBytes) { + internalLogger.warning( + '$runtimeType: Item size ${encoded.length} exceeds buffer limit ${_config.maxBufferSizeBytes}, dropping', + ); + return; + } + + _store(encoded, item); + _bufferSize += encoded.length; + _itemCount++; + + if (_isBufferFull) { + internalLogger.debug( + '$runtimeType: Buffer full, flushing $_itemCount items', + ); + flush(); + } else { + _flushTimer ??= Timer(_config.flushTimeout, flush); + } + } + + @override + FutureOr flush() { + _flushTimer?.cancel(); + _flushTimer = null; + + if (_isEmpty) return null; + + final toFlush = _storage; + final flushedCount = _itemCount; + final flushedSize = _bufferSize; + _storage = _createEmptyStorage(); + _bufferSize = 0; + _itemCount = 0; + + final successMessage = + '$runtimeType: Flushed $flushedCount items ($flushedSize bytes)'; + final errorMessage = + '$runtimeType: Flush failed for $flushedCount items ($flushedSize bytes)'; + + try { + final result = _onFlush(toFlush); + if (result is Future) { + return result.then( + (_) => internalLogger.debug(successMessage), + onError: (exception, stackTrace) => internalLogger.warning( + errorMessage, + error: exception, + stackTrace: stackTrace, + ), + ); + } + internalLogger.debug(successMessage); + } catch (exception, stackTrace) { + internalLogger.warning( + errorMessage, + error: exception, + stackTrace: stackTrace, + ); + } + } +} + +/// In-memory buffer that collects telemetry items as a flat list. +/// +/// Items are encoded and stored in insertion order. On flush, the entire +/// list of encoded items is passed to the [OnFlushCallback]. +final class InMemoryTelemetryBuffer + extends _BaseInMemoryTelemetryBuffer>> { + InMemoryTelemetryBuffer({ + required super.encoder, + required super.onFlush, + super.config, + }) : super(initialStorage: []); + + @override + List> _createEmptyStorage() => []; + + @override + void _store(List encoded, T item) => _storage.add(encoded); + + @override + bool get _isEmpty => _storage.isEmpty; +} diff --git a/packages/dart/lib/src/telemetry/processing/processor.dart b/packages/dart/lib/src/telemetry/processing/processor.dart new file mode 100644 index 0000000000..670835524e --- /dev/null +++ b/packages/dart/lib/src/telemetry/processing/processor.dart @@ -0,0 +1,72 @@ +import 'dart:async'; + +import 'package:meta/meta.dart'; + +import '../../../sentry.dart'; +import '../../utils/internal_logger.dart'; +import 'buffer.dart'; + +/// Interface for processing and buffering telemetry data before sending. +/// +/// Implementations collect logs, buffering them until flushed. +/// This enables batching of telemetry data for efficient transport. +abstract class TelemetryProcessor { + /// Adds a log to be processed and buffered. + void addLog(SentryLog log); + + /// Flushes all buffered telemetry data. + /// + /// Returns a [Future] if any buffer performs async flushing, otherwise + /// returns synchronously. + FutureOr flush(); +} + +/// Default telemetry processor that routes items to type-specific buffers. +/// +/// Logs are dispatched to their respective [TelemetryBuffer] +/// instances. If no buffer is registered for a telemetry type, items are +/// dropped with a warning. +class DefaultTelemetryProcessor implements TelemetryProcessor { + /// The buffer for log data, or `null` if log buffering is disabled. + final TelemetryBuffer? _logBuffer; + + @visibleForTesting + TelemetryBuffer? get logBuffer => _logBuffer; + + DefaultTelemetryProcessor({ + TelemetryBuffer? logBuffer, + }) : _logBuffer = logBuffer; + + @override + void addLog(SentryLog log) { + if (logBuffer == null) { + internalLogger.warning( + '$runtimeType: No buffer registered for ${log.runtimeType} - item was dropped', + ); + return; + } + + logBuffer!.add(log); + } + + @override + FutureOr flush() { + internalLogger.debug('$runtimeType: Clearing buffers'); + + final result = logBuffer?.flush(); + + if (result is Future) { + return result; + } + + return null; + } +} + +class NoOpTelemetryProcessor implements TelemetryProcessor { + @override + void addLog(SentryLog log) {} + + @override + FutureOr flush() {} +} diff --git a/packages/dart/lib/src/telemetry/processing/processor_integration.dart b/packages/dart/lib/src/telemetry/processing/processor_integration.dart new file mode 100644 index 0000000000..cc4fc2ad24 --- /dev/null +++ b/packages/dart/lib/src/telemetry/processing/processor_integration.dart @@ -0,0 +1,37 @@ +import '../../../sentry.dart'; +import '../../utils/internal_logger.dart'; +import 'in_memory_buffer.dart'; +import 'processor.dart'; + +/// Integration that sets up in-memory telemetry processing for Dart. +/// +/// This is the standard processor when no other implementation is provided. +/// It buffers and batches telemetry data in memory before export. +class InMemoryTelemetryProcessorIntegration extends Integration { + static const integrationName = 'InMemoryTelemetryProcessor'; + + @override + void call(Hub hub, SentryOptions options) { + if (options.telemetryProcessor is! NoOpTelemetryProcessor) { + internalLogger.debug( + () => + '$integrationName: ${options.telemetryProcessor.runtimeType} already set, skipping', + ); + return; + } + + options.telemetryProcessor = + DefaultTelemetryProcessor(logBuffer: _createLogBuffer(options)); + + options.sdk.addIntegration(integrationName); + } + + InMemoryTelemetryBuffer _createLogBuffer(SentryOptions options) => + InMemoryTelemetryBuffer( + encoder: (SentryLog item) => utf8JsonEncoder.convert(item.toJson()), + onFlush: (items) { + final envelope = SentryEnvelope.fromLogsData( + items.map((item) => item).toList(), options.sdk); + return options.transport.send(envelope).then((_) {}); + }); +} diff --git a/packages/dart/test/mocks/mock_log_batcher.dart b/packages/dart/test/mocks/mock_log_batcher.dart deleted file mode 100644 index 3c3d79cbbb..0000000000 --- a/packages/dart/test/mocks/mock_log_batcher.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'dart:async'; - -import 'package:sentry/src/protocol/sentry_log.dart'; -import 'package:sentry/src/sentry_log_batcher.dart'; - -class MockLogBatcher implements SentryLogBatcher { - final addLogCalls = []; - final flushCalls = []; - - @override - FutureOr addLog(SentryLog log) { - addLogCalls.add(log); - } - - @override - FutureOr flush() async { - flushCalls.add(null); - } -} diff --git a/packages/dart/test/mocks/mock_telemetry_buffer.dart b/packages/dart/test/mocks/mock_telemetry_buffer.dart new file mode 100644 index 0000000000..da257d2751 --- /dev/null +++ b/packages/dart/test/mocks/mock_telemetry_buffer.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:sentry/src/telemetry/processing/buffer.dart'; + +class MockTelemetryBuffer extends TelemetryBuffer { + final List addedItems = []; + int flushCallCount = 0; + final bool asyncFlush; + + MockTelemetryBuffer({this.asyncFlush = false}); + + @override + void add(T item) => addedItems.add(item); + + @override + FutureOr flush() { + flushCallCount++; + if (asyncFlush) { + return Future.value(); + } + return null; + } +} diff --git a/packages/dart/test/mocks/mock_telemetry_processor.dart b/packages/dart/test/mocks/mock_telemetry_processor.dart new file mode 100644 index 0000000000..a52fd97a2f --- /dev/null +++ b/packages/dart/test/mocks/mock_telemetry_processor.dart @@ -0,0 +1,18 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/processing/processor.dart'; + +class MockTelemetryProcessor implements TelemetryProcessor { + final List addedLogs = []; + int flushCalls = 0; + int closeCalls = 0; + + @override + void addLog(SentryLog log) { + addedLogs.add(log); + } + + @override + void flush() { + flushCalls++; + } +} diff --git a/packages/dart/test/sentry_client_lifecycle_test.dart b/packages/dart/test/sentry_client_lifecycle_test.dart index 18c397a46c..060cb6e261 100644 --- a/packages/dart/test/sentry_client_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_lifecycle_test.dart @@ -4,7 +4,7 @@ import 'package:sentry/src/sentry_tracer.dart'; import 'package:test/test.dart'; import 'mocks/mock_client_report_recorder.dart'; -import 'mocks/mock_log_batcher.dart'; +import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'sentry_client_test.dart'; import 'test_utils.dart'; @@ -41,7 +41,8 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry .registerCallback((event) { @@ -50,9 +51,8 @@ void main() { await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.attributes['test']?.value, "test-value"); expect(capturedLog.attributes['test']?.type, 'string'); @@ -72,7 +72,8 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry .registerCallback((event) { diff --git a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart index 18c397a46c..060cb6e261 100644 --- a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart @@ -4,7 +4,7 @@ import 'package:sentry/src/sentry_tracer.dart'; import 'package:test/test.dart'; import 'mocks/mock_client_report_recorder.dart'; -import 'mocks/mock_log_batcher.dart'; +import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'sentry_client_test.dart'; import 'test_utils.dart'; @@ -41,7 +41,8 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry .registerCallback((event) { @@ -50,9 +51,8 @@ void main() { await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.attributes['test']?.value, "test-value"); expect(capturedLog.attributes['test']?.type, 'string'); @@ -72,7 +72,8 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry .registerCallback((event) { diff --git a/packages/dart/test/sentry_client_test.dart b/packages/dart/test/sentry_client_test.dart index 534f665774..e7c46ab55e 100644 --- a/packages/dart/test/sentry_client_test.dart +++ b/packages/dart/test/sentry_client_test.dart @@ -17,18 +17,16 @@ import 'package:sentry/src/transport/noop_transport.dart'; import 'package:sentry/src/transport/spotlight_http_transport.dart'; import 'package:sentry/src/utils/iterable_utils.dart'; import 'package:test/test.dart'; -import 'package:sentry/src/noop_log_batcher.dart'; -import 'package:sentry/src/sentry_log_batcher.dart'; import 'package:mockito/mockito.dart'; import 'package:http/http.dart' as http; import 'mocks.dart'; import 'mocks/mock_client_report_recorder.dart'; import 'mocks/mock_hub.dart'; +import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'test_utils.dart'; import 'utils/url_details_test.dart'; -import 'mocks/mock_log_batcher.dart'; void main() { group('SentryClient captures message', () { @@ -1734,41 +1732,32 @@ void main() { ); } - test('sets log batcher on options when logs are enabled', () async { - expect(fixture.options.logBatcher is NoopLogBatcher, true); - - fixture.options.enableLogs = true; - fixture.getSut(); - - expect(fixture.options.logBatcher is NoopLogBatcher, false); - }); - test('disabled by default', () async { final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls, isEmpty); + expect(mockProcessor.addedLogs, isEmpty); }); test('should capture logs as envelope', () async { fixture.options.enableLogs = true; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); + expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.traceId, log.traceId); expect(capturedLog.level, log.level); @@ -1789,13 +1778,13 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect( capturedLog.attributes['sentry.sdk.name']?.value, @@ -1843,7 +1832,8 @@ void main() { fixture.options.enableLogs = true; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); final scope = Scope(fixture.options); @@ -1851,9 +1841,8 @@ void main() { await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.attributes['from_scope']?.value, 12); }); @@ -1861,7 +1850,8 @@ void main() { fixture.options.enableLogs = true; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); final scope = Scope(fixture.options); @@ -1875,9 +1865,8 @@ void main() { await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final captured = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final captured = mockProcessor.addedLogs.first; expect(captured.attributes['overridden']?.value, 'fromLog'); expect(captured.attributes['kept']?.value, true); @@ -1897,13 +1886,13 @@ void main() { await scope.setUser(user); final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect( capturedLog.attributes['user.id']?.value, @@ -1937,16 +1926,16 @@ void main() { fixture.options.enableLogs = true; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); final scope = Scope(fixture.options); await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.traceId, scope.propagationContext.traceId); }); @@ -1958,14 +1947,14 @@ void main() { fixture.options.beforeSendLog = (log) => null; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 0); + expect(mockProcessor.addedLogs.length, 0); expect( fixture.recorder.discardedEvents.first.reason, @@ -1985,15 +1974,15 @@ void main() { }; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.body, 'modified'); }); @@ -2007,15 +1996,15 @@ void main() { }; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.body, 'modified'); }); @@ -2029,14 +2018,14 @@ void main() { }; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; final log = givenLog(); await client.captureLog(log); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.body, 'test'); }); @@ -2053,7 +2042,8 @@ void main() { scope.span = span; final client = fixture.getSut(); - fixture.options.logBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); + fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry .registerCallback((event) { @@ -2062,9 +2052,8 @@ void main() { await client.captureLog(log, scope: scope); - final mockLogBatcher = fixture.options.logBatcher as MockLogBatcher; - expect(mockLogBatcher.addLogCalls.length, 1); - final capturedLog = mockLogBatcher.addLogCalls.first; + expect(mockProcessor.addedLogs.length, 1); + final capturedLog = mockProcessor.addedLogs.first; expect(capturedLog.attributes['test']?.value, "test-value"); expect(capturedLog.attributes['test']?.type, 'string'); @@ -2678,15 +2667,15 @@ void main() { final flushCompleter = Completer(); bool flushStarted = false; - // Create a mock log batcher with async flush - final mockLogBatcher = MockLogBatcherWithAsyncFlush( + // Create a mock telemetry processor with async flush + final mockProcessor = MockTelemetryProcessorWithAsyncFlush( onFlush: () async { flushStarted = true; // Wait for the completer to complete await flushCompleter.future; }, ); - fixture.options.logBatcher = mockLogBatcher; + fixture.options.telemetryProcessor = mockProcessor; // Start close() in the background final closeFuture = client.close(); @@ -2904,20 +2893,14 @@ class Fixture { class MockHttpClient extends Mock implements http.Client {} -class MockLogBatcherWithAsyncFlush implements SentryLogBatcher { +class MockTelemetryProcessorWithAsyncFlush extends MockTelemetryProcessor { final Future Function() onFlush; - final addLogCalls = []; - - MockLogBatcherWithAsyncFlush({required this.onFlush}); - @override - void addLog(SentryLog log) { - addLogCalls.add(log); - } + MockTelemetryProcessorWithAsyncFlush({required this.onFlush}); @override FutureOr flush() async { - await onFlush(); + return onFlush(); } } diff --git a/packages/dart/test/sentry_log_batcher_test.dart b/packages/dart/test/sentry_log_batcher_test.dart deleted file mode 100644 index dda0eabaa4..0000000000 --- a/packages/dart/test/sentry_log_batcher_test.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:async'; - -import 'package:sentry/sentry.dart'; -import 'package:sentry/src/sentry_log_batcher.dart'; -import 'package:test/test.dart'; - -import 'mocks/mock_transport.dart'; - -void main() { - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - test('added logs are flushed after timeout', () async { - final flushTimeout = Duration(milliseconds: 1); - - final batcher = fixture.getSut(flushTimeout: flushTimeout); - - final log = SentryLog( - timestamp: DateTime.now(), - level: SentryLogLevel.info, - body: 'test', - attributes: {}, - ); - final log2 = SentryLog( - timestamp: DateTime.now(), - level: SentryLogLevel.info, - body: 'test2', - attributes: {}, - ); - - batcher.addLog(log); - batcher.addLog(log2); - - expect(fixture.mockTransport.envelopes.length, 0); - - await Future.delayed(flushTimeout); - - expect(fixture.mockTransport.envelopes.length, 1); - - final envelopePayloadJson = (fixture.mockTransport).logs.first; - - expect(envelopePayloadJson, isNotNull); - expect(envelopePayloadJson['items'].length, 2); - expect(envelopePayloadJson['items'].first['body'], log.body); - expect(envelopePayloadJson['items'].last['body'], log2.body); - }); - - test('logs exeeding max size are flushed without timeout', () async { - // Use a buffer size that can hold multiple logs before triggering flush - // Each log is ~153 bytes, so 300 bytes can hold 1 log, triggering flush on 2nd - final batcher = fixture.getSut(maxBufferSizeBytes: 300); - - final log = SentryLog( - timestamp: DateTime.now(), - level: SentryLogLevel.info, - body: 'test', - attributes: {}, - ); - - // Add first log - should fit in buffer - batcher.addLog(log); - expect(fixture.mockTransport.envelopes.length, 0); - - // Add second log - should exceed buffer and trigger flush - batcher.addLog(log); - - // Just wait a little bit, as we call capture without awaiting internally. - await Future.delayed(Duration(milliseconds: 1)); - - expect(fixture.mockTransport.envelopes.length, 1); - final envelopePayloadJson = (fixture.mockTransport).logs.first; - - expect(envelopePayloadJson, isNotNull); - expect(envelopePayloadJson['items'].length, 2); - }); - - test('calling flush directly flushes logs', () async { - final batcher = fixture.getSut(); - - final log = SentryLog( - timestamp: DateTime.now(), - level: SentryLogLevel.info, - body: 'test', - attributes: {}, - ); - - batcher.addLog(log); - batcher.addLog(log); - batcher.flush(); - - // Just wait a little bit, as we call capture without awaiting internally. - await Future.delayed(Duration(milliseconds: 1)); - - expect(fixture.mockTransport.envelopes.length, 1); - final envelopePayloadJson = (fixture.mockTransport).logs.first; - - expect(envelopePayloadJson, isNotNull); - expect(envelopePayloadJson['items'].length, 2); - }); - - test('timeout is only started once and not restarted on subsequent additions', - () async { - final flushTimeout = Duration(milliseconds: 100); - final batcher = fixture.getSut(flushTimeout: flushTimeout); - - final log = SentryLog( - timestamp: DateTime.now(), - level: SentryLogLevel.info, - body: 'test', - attributes: {}, - ); - - // Add first log - should start timer - batcher.addLog(log); - expect(fixture.mockTransport.envelopes.length, 0); - - // Add second log immediately - should NOT restart timer - batcher.addLog(log); - expect(fixture.mockTransport.envelopes.length, 0); - - // Wait for timeout to fire - await Future.delayed(flushTimeout + Duration(milliseconds: 10)); - - // Should have sent both logs after timeout - expect(fixture.mockTransport.envelopes.length, 1); - final envelopePayloadJson = (fixture.mockTransport).logs.first; - expect(envelopePayloadJson['items'].length, 2); - }); -} - -class Fixture { - final options = SentryOptions(); - final mockTransport = MockTransport(); - - Fixture() { - options.transport = mockTransport; - } - - SentryLogBatcher getSut({Duration? flushTimeout, int? maxBufferSizeBytes}) { - return SentryLogBatcher( - options, - flushTimeout: flushTimeout, - maxBufferSizeBytes: maxBufferSizeBytes, - ); - } -} diff --git a/packages/dart/test/sentry_test.dart b/packages/dart/test/sentry_test.dart index 9230d71396..ffb609b062 100644 --- a/packages/dart/test/sentry_test.dart +++ b/packages/dart/test/sentry_test.dart @@ -8,6 +8,7 @@ import 'package:sentry/src/dart_exception_type_identifier.dart'; import 'package:sentry/src/event_processor/deduplication_event_processor.dart'; import 'package:sentry/src/logs_enricher_integration.dart'; import 'package:sentry/src/feature_flags_integration.dart'; +import 'package:sentry/src/telemetry/processing/processor_integration.dart'; import 'package:test/test.dart'; import 'mocks.dart'; @@ -319,6 +320,27 @@ void main() { ); }); + test('should add $InMemoryTelemetryProcessorIntegration', () async { + late SentryOptions optionsReference; + final options = defaultTestOptions(); + + await Sentry.init( + options: options, + (options) { + options.dsn = fakeDsn; + optionsReference = options; + }, + appRunner: appRunner, + ); + + expect( + optionsReference.integrations + .whereType() + .length, + 1, + ); + }); + test('should add only web compatible default integrations', () async { final options = defaultTestOptions(); await Sentry.init( diff --git a/packages/dart/test/telemetry/processing/buffer_test.dart b/packages/dart/test/telemetry/processing/buffer_test.dart new file mode 100644 index 0000000000..fe5335f743 --- /dev/null +++ b/packages/dart/test/telemetry/processing/buffer_test.dart @@ -0,0 +1,201 @@ +import 'dart:convert'; + +import 'package:sentry/src/telemetry/processing/in_memory_buffer.dart'; +import 'package:sentry/src/telemetry/processing/buffer_config.dart'; +import 'package:test/test.dart'; + +void main() { + group('InMemoryTelemetryBuffer', () { + late _SimpleFixture fixture; + + setUp(() { + fixture = _SimpleFixture(); + }); + + test('items are flushed after timeout', () async { + final flushTimeout = Duration(milliseconds: 1); + final buffer = fixture.getSut( + config: TelemetryBufferConfig(flushTimeout: flushTimeout), + ); + + buffer.add(_TestItem('item1')); + buffer.add(_TestItem('item2')); + + expect(fixture.flushedItems, isEmpty); + + await Future.delayed(flushTimeout + Duration(milliseconds: 10)); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(2)); + }); + + test('items exceeding max size are flushed immediately', () async { + // Each item encodes to ~14 bytes ({"id":"item1"}), so 20 bytes triggers flush on 2nd item + final buffer = fixture.getSut( + config: TelemetryBufferConfig(maxBufferSizeBytes: 20), + ); + + buffer.add(_TestItem('item1')); + expect(fixture.flushCallCount, 0); + + buffer.add(_TestItem('item2')); + + // Wait briefly for async flush + await Future.delayed(Duration(milliseconds: 1)); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(2)); + }); + + test('single item exceeding max buffer size is rejected', () async { + // Set max buffer size to 10 bytes, but item encodes to ~14 bytes + final buffer = fixture.getSut( + config: TelemetryBufferConfig(maxBufferSizeBytes: 10), + ); + + buffer.add(_TestItem('item1')); + + // Item should be rejected, not added to buffer + await buffer.flush(); + + expect(fixture.flushedItems, isEmpty); + }); + + test('items exceeding max item count are flushed immediately', () async { + final buffer = fixture.getSut( + config: TelemetryBufferConfig(maxItemCount: 2), + ); + + buffer.add(_TestItem('item1')); + expect(fixture.flushCallCount, 0); + + buffer.add(_TestItem('item2')); + + // Wait briefly for async flush + await Future.delayed(Duration(milliseconds: 1)); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(2)); + }); + + test('calling flush directly sends items', () async { + final buffer = fixture.getSut(); + + buffer.add(_TestItem('item1')); + buffer.add(_TestItem('item2')); + + await buffer.flush(); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(2)); + }); + + test('timer is only started once and not restarted on subsequent additions', + () async { + final flushTimeout = Duration(milliseconds: 100); + final buffer = fixture.getSut( + config: TelemetryBufferConfig(flushTimeout: flushTimeout), + ); + + buffer.add(_TestItem('item1')); + expect(fixture.flushCallCount, 0); + + buffer.add(_TestItem('item2')); + expect(fixture.flushCallCount, 0); + + await Future.delayed(flushTimeout + Duration(milliseconds: 10)); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(2)); + }); + + test('flush with empty buffer returns null', () async { + final buffer = fixture.getSut(); + + final result = buffer.flush(); + + expect(result, isNull); + expect(fixture.flushedItems, isEmpty); + }); + + test('buffer is cleared after flush', () async { + final buffer = fixture.getSut(); + + buffer.add(_TestItem('item1')); + await buffer.flush(); + + expect(fixture.flushCallCount, 1); + expect(fixture.flushedItems, hasLength(1)); + + // Second flush should not send anything + fixture.reset(); + final result = buffer.flush(); + + expect(result, isNull); + expect(fixture.flushCallCount, 0); + expect(fixture.flushedItems, isEmpty); + }); + + test('encoding failure does not crash and item is skipped', () async { + final buffer = fixture.getSut(); + + buffer.add(_ThrowingTestItem()); + buffer.add(_TestItem('valid')); + await buffer.flush(); + + // Only the valid item should be in the buffer + expect(fixture.flushedItems, hasLength(1)); + expect(fixture.flushCallCount, 1); + }); + + test('onFlush receives List> directly', () async { + final buffer = fixture.getSut(); + + buffer.add(_TestItem('item1')); + buffer.add(_TestItem('item2')); + await buffer.flush(); + + // Verify callback received a simple list, not a map + expect(fixture.flushedItems, hasLength(2)); + expect(fixture.flushCallCount, 1); + }); + }); +} + +class _TestItem { + final String id; + + _TestItem(this.id); + + Map toJson() => {'id': id}; +} + +class _ThrowingTestItem extends _TestItem { + _ThrowingTestItem() : super('throwing'); + + @override + Map toJson() => throw Exception('Encoding failed'); +} + +class _SimpleFixture { + List> flushedItems = []; + int flushCallCount = 0; + + InMemoryTelemetryBuffer<_TestItem> getSut({ + TelemetryBufferConfig config = const TelemetryBufferConfig(), + }) { + return InMemoryTelemetryBuffer<_TestItem>( + encoder: (item) => utf8.encode(jsonEncode(item.toJson())), + onFlush: (items) { + flushCallCount++; + flushedItems = items; + }, + config: config, + ); + } + + void reset() { + flushedItems = []; + flushCallCount = 0; + } +} diff --git a/packages/dart/test/telemetry/processing/processor_integration_test.dart b/packages/dart/test/telemetry/processing/processor_integration_test.dart new file mode 100644 index 0000000000..b0a41d07f4 --- /dev/null +++ b/packages/dart/test/telemetry/processing/processor_integration_test.dart @@ -0,0 +1,96 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/processing/in_memory_buffer.dart'; +import 'package:sentry/src/telemetry/processing/processor.dart'; +import 'package:sentry/src/telemetry/processing/processor_integration.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mock_hub.dart'; +import '../../mocks/mock_transport.dart'; +import '../../test_utils.dart'; + +void main() { + group('DefaultTelemetryProcessorIntegration', () { + late _Fixture fixture; + + setUp(() { + fixture = _Fixture(); + }); + + test( + 'sets up DefaultTelemetryProcessor when NoOpTelemetryProcessor is active', + () { + final options = fixture.options; + expect(options.telemetryProcessor, isA()); + + fixture.getSut().call(fixture.hub, options); + + expect(options.telemetryProcessor, isA()); + }); + + test('does not override existing telemetry processor', () { + final options = fixture.options; + final existingProcessor = DefaultTelemetryProcessor(); + options.telemetryProcessor = existingProcessor; + + fixture.getSut().call(fixture.hub, options); + + expect(identical(options.telemetryProcessor, existingProcessor), isTrue); + }); + + test('adds integration name to SDK', () { + final options = fixture.options; + + fixture.getSut().call(fixture.hub, options); + + expect( + options.sdk.integrations, + contains(InMemoryTelemetryProcessorIntegration.integrationName), + ); + }); + + test('configures log buffer as InMemoryTelemetryBuffer', () { + final options = fixture.options; + + fixture.getSut().call(fixture.hub, options); + + final processor = options.telemetryProcessor as DefaultTelemetryProcessor; + expect(processor.logBuffer, isA>()); + }); + + group('flush', () { + test('log reaches transport as envelope', () async { + final options = fixture.options; + fixture.getSut().call(fixture.hub, options); + + final processor = + options.telemetryProcessor as DefaultTelemetryProcessor; + processor.addLog(fixture.createLog()); + await processor.flush(); + + expect(fixture.transport.envelopes, hasLength(1)); + }); + }); + }); +} + +class _Fixture { + final hub = MockHub(); + final transport = MockTransport(); + late SentryOptions options; + + _Fixture() { + options = defaultTestOptions()..transport = transport; + } + + InMemoryTelemetryProcessorIntegration getSut() => + InMemoryTelemetryProcessorIntegration(); + + SentryLog createLog() { + return SentryLog( + timestamp: DateTime.now().toUtc(), + level: SentryLogLevel.info, + body: 'test log', + attributes: {}, + ); + } +} diff --git a/packages/dart/test/telemetry/processing/processor_test.dart b/packages/dart/test/telemetry/processing/processor_test.dart new file mode 100644 index 0000000000..64b8476d1b --- /dev/null +++ b/packages/dart/test/telemetry/processing/processor_test.dart @@ -0,0 +1,100 @@ +import 'dart:async'; + +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/processing/processor.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mock_telemetry_buffer.dart'; +import '../../test_utils.dart'; + +void main() { + group('DefaultTelemetryProcessor', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('addLog', () { + test('routes log to log buffer', () { + final mockLogBuffer = MockTelemetryBuffer(); + final processor = + fixture.getSut(enableLogs: true, logBuffer: mockLogBuffer); + + final log = fixture.createLog(); + processor.addLog(log); + + expect(mockLogBuffer.addedItems.length, 1); + expect(mockLogBuffer.addedItems.first, log); + }); + + test('does not throw when no log buffer registered', () { + final processor = fixture.getSut(); + + final log = fixture.createLog(); + processor.addLog(log); + }); + }); + + group('flush', () { + test('flushes all registered buffers', () async { + final mockLogBuffer = MockTelemetryBuffer(); + final processor = fixture.getSut( + enableLogs: true, + logBuffer: mockLogBuffer, + ); + + await processor.flush(); + + expect(mockLogBuffer.flushCallCount, 1); + }); + + test('returns sync (null) when all buffers flush synchronously', () { + final mockLogBuffer = MockTelemetryBuffer(asyncFlush: false); + final processor = fixture.getSut(logBuffer: mockLogBuffer); + + final result = processor.flush(); + + expect(result, isNull); + }); + + test('returns Future when at least one buffer flushes asynchronously', + () async { + final mockLogBuffer = MockTelemetryBuffer(asyncFlush: true); + final processor = fixture.getSut(logBuffer: mockLogBuffer); + + final result = processor.flush(); + + expect(result, isA()); + await result; + }); + }); + }); +} + +class Fixture { + late SentryOptions options; + + Fixture() { + options = defaultTestOptions(); + } + + DefaultTelemetryProcessor getSut({ + bool enableLogs = false, + MockTelemetryBuffer? logBuffer, + }) { + options.enableLogs = enableLogs; + return DefaultTelemetryProcessor( + logBuffer: logBuffer, + ); + } + + SentryLog createLog({String body = 'test log'}) { + return SentryLog( + timestamp: DateTime.now().toUtc(), + level: SentryLogLevel.info, + body: body, + attributes: {}, + ); + } +} diff --git a/packages/flutter/lib/src/widgets_binding_observer.dart b/packages/flutter/lib/src/widgets_binding_observer.dart index f26a080bcd..12811068e1 100644 --- a/packages/flutter/lib/src/widgets_binding_observer.dart +++ b/packages/flutter/lib/src/widgets_binding_observer.dart @@ -94,7 +94,7 @@ class SentryWidgetsBindingObserver with WidgetsBindingObserver { if (!_isNavigatorObserverCreated() && !_options.platform.isWeb) { if (state == AppLifecycleState.inactive) { _appInBackgroundStopwatch.start(); - _options.logBatcher.flush(); + _options.telemetryProcessor.flush(); } else if (_appInBackgroundStopwatch.isRunning && state == AppLifecycleState.resumed) { _appInBackgroundStopwatch.stop(); diff --git a/packages/flutter/test/mocks.dart b/packages/flutter/test/mocks.dart index dec5362a20..af190bf78e 100644 --- a/packages/flutter/test/mocks.dart +++ b/packages/flutter/test/mocks.dart @@ -8,6 +8,7 @@ import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:sentry/src/platform/platform.dart'; import 'package:sentry/src/sentry_tracer.dart'; +import 'package:sentry/src/telemetry/processing/processor.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/frames_tracking/sentry_delayed_frames_tracker.dart'; import 'package:sentry_flutter/src/navigation/time_to_display_tracker.dart'; @@ -236,3 +237,19 @@ class MockLogItem { const MockLogItem(this.level, this.message, {this.logger, this.exception, this.stackTrace}); } + +class MockTelemetryProcessor implements TelemetryProcessor { + final List addedLogs = []; + int flushCalls = 0; + int closeCalls = 0; + + @override + void addLog(SentryLog log) { + addedLogs.add(log); + } + + @override + void flush() { + flushCalls++; + } +} diff --git a/packages/flutter/test/widgets_binding_observer_test.dart b/packages/flutter/test/widgets_binding_observer_test.dart index d4ed7e8a52..8470de76d7 100644 --- a/packages/flutter/test/widgets_binding_observer_test.dart +++ b/packages/flutter/test/widgets_binding_observer_test.dart @@ -1,7 +1,6 @@ // ignore_for_file: invalid_use_of_internal_member import 'dart:ui'; -import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -11,8 +10,6 @@ import 'package:sentry/src/platform/mock_platform.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/widgets_binding_observer.dart'; -import 'package:sentry/src/sentry_log_batcher.dart'; - import 'mocks.dart'; import 'mocks.mocks.dart'; @@ -567,17 +564,17 @@ void main() { }); testWidgets( - 'calls flush on logs batcher when transitioning to inactive state', + 'calls flush on telemetry processor when transitioning to inactive state', (WidgetTester tester) async { final hub = MockHub(); - final mockLogBatcher = MockLogBatcher(); + final mockProcessor = MockTelemetryProcessor(); final options = defaultTestOptions(); options.platform = MockPlatform(isWeb: false); options.bindingUtils = TestBindingWrapper(); - options.logBatcher = mockLogBatcher; + options.telemetryProcessor = mockProcessor; options.enableLogs = true; final observer = SentryWidgetsBindingObserver( @@ -590,21 +587,9 @@ void main() { await sendLifecycle('inactive'); - expect(mockLogBatcher.flushCalled, true); + expect(mockProcessor.flushCalls, 1); instance.removeObserver(observer); }); }); } - -class MockLogBatcher implements SentryLogBatcher { - var flushCalled = false; - - @override - void addLog(SentryLog log) {} - - @override - FutureOr flush() async { - flushCalled = true; - } -} From f57925071451ff33f01fe54d7b475a11eff59f49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 16:05:45 +0100 Subject: [PATCH 18/62] chore(deps): update Flutter SDK (metrics) to v3.38.7 (#3437) * chore: update metrics/flutter.properties to 3.38.7 * update * update * Update --------- Co-authored-by: GitHub Co-authored-by: Giancarlo Buenaflor --- .github/workflows/flutter.yml | 3 +-- metrics/flutter.properties | 2 +- .../example/macos/Runner.xcodeproj/project.pbxproj | 14 ++++++++++---- .../xcshareddata/xcschemes/Runner.xcscheme | 3 ++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 91cf1c1b5b..bacb30181a 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -136,7 +136,7 @@ jobs: - name: Run on macOS if: matrix.target == 'macos' - run: flutter build macos + run: flutter build macos --debug analyze: uses: ./.github/workflows/analyze.yml @@ -189,7 +189,6 @@ jobs: reporter: github-pr-review android: true fail_on_error: true - # TODO: disabled until the following is fixed https://github.com/natiginfo/action-detekt-all/issues/73 # detekt: # runs-on: ubuntu-latest diff --git a/metrics/flutter.properties b/metrics/flutter.properties index 87e880bdc2..39f226238d 100644 --- a/metrics/flutter.properties +++ b/metrics/flutter.properties @@ -1,2 +1,2 @@ -version = 3.38.5 +version = 3.38.7 repo = https://github.com/flutter/flutter diff --git a/packages/flutter/example/macos/Runner.xcodeproj/project.pbxproj b/packages/flutter/example/macos/Runner.xcodeproj/project.pbxproj index ad9c506c71..18ff62e7d0 100644 --- a/packages/flutter/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/flutter/example/macos/Runner.xcodeproj/project.pbxproj @@ -209,7 +209,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { @@ -412,7 +412,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -427,8 +427,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 97JCY7859U; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -492,7 +494,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -539,7 +541,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -554,8 +556,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 97JCY7859U; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -575,8 +579,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 97JCY7859U; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/packages/flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 99a6840afc..b8d62e7b12 100644 --- a/packages/flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/flutter/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ From 0265ce50dae6d461ffddf6c49dfddb7070f437e2 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 15 Jan 2026 16:29:30 +0100 Subject: [PATCH 19/62] fix: update kotlin version handling in android (#3436) * update kotlin version handling in android build scripts for CI compatibility * Fix Kotlin version format in workflow file * Update * Update * Update * Remove CI override comment for Kotlin language version Removed comment about allowing CI to override Kotlin language version. --- .../kotlin-version-compatibility.yml | 66 +++++++++++++++++++ CHANGELOG.md | 4 ++ packages/flutter/android/build.gradle | 1 - .../flutter/example/android/app/build.gradle | 2 +- .../flutter/example/android/settings.gradle | 14 +++- 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/kotlin-version-compatibility.yml diff --git a/.github/workflows/kotlin-version-compatibility.yml b/.github/workflows/kotlin-version-compatibility.yml new file mode 100644 index 0000000000..be86fb1cdc --- /dev/null +++ b/.github/workflows/kotlin-version-compatibility.yml @@ -0,0 +1,66 @@ +name: Kotlin Version Compatibility + +on: + push: + branches: + - main + - release/** + pull_request: + paths: + - ".github/workflows/kotlin-version-compatibility.yml" + - "packages/flutter/android/**" + - "packages/flutter/example/android/**" + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-apk-kotlin-versions: + name: "APK | Kotlin lang ${{ matrix.kotlin_language_version }}" + runs-on: ubuntu-latest + timeout-minutes: 30 + defaults: + run: + working-directory: packages/flutter/example + strategy: + fail-fast: false + matrix: + include: + - kotlin_language_version: "1.7" + kotlin_android_plugin_version: "2.0.21" + - kotlin_language_version: "2.3" + kotlin_android_plugin_version: "2.3.0" + + env: + KOTLIN_LANGUAGE_VERSION: ${{ matrix.kotlin_language_version }} + KOTLIN_ANDROID_PLUGIN_VERSION: ${{ matrix.kotlin_android_plugin_version }} + + steps: + - uses: actions/checkout@v5 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "17" + + - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 + with: + channel: stable + + - name: Flutter pub get + run: flutter pub get + + - name: Build APK | Kotlin lang ${{ matrix.kotlin_language_version }} | plugin ${{ matrix.kotlin_android_plugin_version }} + run: flutter build apk --debug --target-platform=android-x64 + + - name: Verify build artifacts + run: | + if [ -f "build/app/outputs/flutter-apk/app-debug.apk" ]; then + echo "APK build successful with Kotlin language version ${{ matrix.kotlin_language_version }}" + ls -lh build/app/outputs/flutter-apk/app-debug.apk + else + echo "APK build failed - artifact not found" + exit 1 + fi diff --git a/CHANGELOG.md b/CHANGELOG.md index e06a63c8d3..e966cd1a46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- Kotlin language version handling in Android ([#3436](https://github.com/getsentry/sentry-dart/pull/3436)) + ### Enhancements - Replace log batcher with telemetry processor ([#3448](https://github.com/getsentry/sentry-dart/pull/3448)) diff --git a/packages/flutter/android/build.gradle b/packages/flutter/android/build.gradle index 43c7a10e08..f71518ee1f 100644 --- a/packages/flutter/android/build.gradle +++ b/packages/flutter/android/build.gradle @@ -58,7 +58,6 @@ android { } kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8 - languageVersion = "1.8" } } diff --git a/packages/flutter/example/android/app/build.gradle b/packages/flutter/example/android/app/build.gradle index 5f9c0798ee..f7d077feff 100644 --- a/packages/flutter/example/android/app/build.gradle +++ b/packages/flutter/example/android/app/build.gradle @@ -34,7 +34,7 @@ android { } kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8 - languageVersion = "1.8" + languageVersion = System.getenv("KOTLIN_LANGUAGE_VERSION") ?: "1.7" } compileSdkVersion 35 diff --git a/packages/flutter/example/android/settings.gradle b/packages/flutter/example/android/settings.gradle index 836310ef9a..7edfb3a470 100644 --- a/packages/flutter/example/android/settings.gradle +++ b/packages/flutter/example/android/settings.gradle @@ -1,4 +1,12 @@ pluginManagement { + def kotlinAndroidVersion = System.getenv("KOTLIN_ANDROID_PLUGIN_VERSION") ?: "2.0.21" + + plugins { + id "org.jetbrains.kotlin.android" version kotlinAndroidVersion + id "com.android.application" version "8.2.2" + id "io.sentry.android.gradle" version "4.14.1" + } + def flutterSdkPath = { def properties = new Properties() file("local.properties").withInputStream { properties.load(it) } @@ -18,9 +26,9 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.2.2" apply false - id "org.jetbrains.kotlin.android" version "2.0.21" apply false - id "io.sentry.android.gradle" version "4.14.1" apply false + id "com.android.application" apply false + id "org.jetbrains.kotlin.android" apply false + id "io.sentry.android.gradle" apply false } include ":app" From 862fe42704156adbaf2c45bca15a80469e2c9ed5 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 15 Jan 2026 15:30:33 +0000 Subject: [PATCH 20/62] release: 9.10.0 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e966cd1a46..cc9328eefd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.10.0 ### Fixes diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index e7500806ed..aa560c82ed 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.10.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.9.2 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.1 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index 9f4de328d0..e588e30755 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index c7ed392184..f0c652d72a 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.9.2 +version: 9.10.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index a6e5757ec8..462649248d 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index f0fc180c71..ad1f86fe57 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.9.2 + sentry: 9.10.0 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index 1617c084cc..a06123883a 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 3e05459fdb..183f5a0da0 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.9.2 + sentry: 9.10.0 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 9c8e3ac051..9347900f4d 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index a6af6fa782..f8c09eb8b3 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.9.2 + sentry: 9.10.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index d2fdedecf1..e052966065 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.9.2 + sentry: 9.10.0 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index f1a47ac549..7763ceb785 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.9.2 +version: 9.10.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 73989c208c..184306e03b 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index ef890b9260..655ba9030d 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.9.2 +version: 9.10.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.9.2 + sentry: 9.10.0 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index 73de810436..f307eda4fe 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index b366ebe711..4047717c39 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.9.2 + sentry: 9.10.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index 35b5137d23..3536b493e2 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index 0e31e77dfd..a1d7b9fe3c 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.9.2 + sentry: 9.10.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index 85f648270c..4d3ecff900 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.9.2 + sentry: 9.10.0 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index d63cbd8707..e4669cc52b 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index cf7eb3ebbf..534a03de2b 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.9.2 + sentry: 9.10.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index ed17928067..5c40e70bf3 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.9.2'; +const String sdkVersion = '9.10.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index b687f9c6f2..8fe449b308 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.9.2 + sentry: 9.10.0 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 97ff945ecd..44db042557 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.9.2 +version: 9.10.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -10,7 +10,7 @@ environment: dependencies: http: ^1.3.0 - sentry: 9.9.2 + sentry: 9.10.0 dev_dependencies: supabase: ^2.6.0 From 2bcb18bdaadddf4e9b57d64ca629eb3f313117a8 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 15 Jan 2026 18:05:11 +0100 Subject: [PATCH 21/62] Update Xcode version to 16.4 in workflow (#3452) --- .github/workflows/testflight.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index c3190687d6..32ccb3dceb 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - - run: xcodes select 16.3 + - run: xcodes select 16.4 - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 with: ruby-version: '2.7.5' From 02d3df329fbec06471935a5b6ab1c102600ec834 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 19 Jan 2026 16:12:31 +0100 Subject: [PATCH 22/62] fix(ci): failing package-analysis (#3453) * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Fix analyze * Refactor Pana score check logic in analyze.yml --- .github/workflows/analyze.yml | 14 +++++++------- .github/workflows/dart.yml | 1 - .github/workflows/file.yml | 1 - .github/workflows/flutter.yml | 1 - .github/workflows/hive.yml | 1 - packages/file/analysis_options.yaml | 1 + packages/link/analysis_options.yaml | 4 +++- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index dfaaed3e0a..dd95847b6a 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -9,10 +9,10 @@ on: type: string default: dart panaThreshold: - description: Minumum percentage of Dart Package Analyzer score that must be achieved. + description: Minimum number of points that must be achieved. required: false type: number - default: 100 + default: 140 jobs: analyze: @@ -62,7 +62,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Apply dependency override - if: ${{ inputs.package == 'flutter' }} + if: ${{ inputs.package != 'packages/dart' }} working-directory: ${{ inputs.package }} run: | sed -i.bak 's|sentry:.*|sentry:\n path: /github/workspace/packages/dart|g' pubspec.yaml @@ -77,9 +77,9 @@ jobs: TOTAL_MAX: ${{ steps.analysis.outputs.total_max }} PANA_THRESHOLD: ${{ inputs.panaThreshold }} run: | - PERCENTAGE=$(( $TOTAL * 100 / $TOTAL_MAX )) - if (( $PERCENTAGE < $PANA_THRESHOLD )) - then - echo "Score too low ($PERCENTAGE % is less than the expected $PANA_THRESHOLD %)!" + if (( TOTAL < PANA_THRESHOLD )); then + echo "Pana score check failed: ${TOTAL}/${TOTAL_MAX} points (minimum required: ${PANA_THRESHOLD})." exit 1 + else + echo "Pana score check passed: ${TOTAL}/${TOTAL_MAX} points (minimum required: ${PANA_THRESHOLD})." fi diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 77ab731a8f..9703629016 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -61,4 +61,3 @@ jobs: uses: ./.github/workflows/analyze.yml with: package: packages/dart - panaThreshold: 87 diff --git a/.github/workflows/file.yml b/.github/workflows/file.yml index 51e98f02b3..75d602c05b 100644 --- a/.github/workflows/file.yml +++ b/.github/workflows/file.yml @@ -50,4 +50,3 @@ jobs: uses: ./.github/workflows/analyze.yml with: package: packages/file - panaThreshold: 90 diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index bacb30181a..49210e7d1b 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -143,7 +143,6 @@ jobs: with: package: packages/flutter sdk: flutter - panaThreshold: 87 pod-lint: runs-on: macos-15 diff --git a/.github/workflows/hive.yml b/.github/workflows/hive.yml index 3e99e15d25..ec4642c0ff 100644 --- a/.github/workflows/hive.yml +++ b/.github/workflows/hive.yml @@ -50,4 +50,3 @@ jobs: uses: ./.github/workflows/analyze.yml with: package: packages/hive - panaThreshold: 90 diff --git a/packages/file/analysis_options.yaml b/packages/file/analysis_options.yaml index 3dd01b96b7..126ce78598 100644 --- a/packages/file/analysis_options.yaml +++ b/packages/file/analysis_options.yaml @@ -8,6 +8,7 @@ analyzer: missing_required_param: error # treat missing returns as a warning (not a hint) missing_return: error + invalid_dependency: ignore language: strict-casts: true strict-inference: true diff --git a/packages/link/analysis_options.yaml b/packages/link/analysis_options.yaml index c127277900..c9aaec4cf1 100644 --- a/packages/link/analysis_options.yaml +++ b/packages/link/analysis_options.yaml @@ -10,4 +10,6 @@ analyzer: language: strict-casts: true strict-inference: true - strict-raw-types: true \ No newline at end of file + strict-raw-types: true + errors: + invalid_dependency: ignore \ No newline at end of file From 8403e81cb1a7a3769aa29a1b1ac1c5195a6d0473 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 20 Jan 2026 10:47:52 +0100 Subject: [PATCH 23/62] chore: ignore local Claude settings (#3462) Add .claude/settings.local.json to .gitignore to prevent committing local Claude Code configuration. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 1df9821de0..42cbdaf05e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ Podfile.lock .gradle packages/flutter/.gradle + +# Local Claude Code settings that should not be committed +.claude/settings.local.json From 7f626a21e83f5a2a1fc0f084a1b1641a30f4c2b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 11:32:58 +0100 Subject: [PATCH 24/62] chore: update packages/flutter/scripts/update-android.sh to 8.30.0 (#3451) Co-authored-by: GitHub --- CHANGELOG.md | 8 + packages/flutter/android/build.gradle | 2 +- .../flutter/lib/src/native/java/binding.dart | 1494 +++++++++++------ 3 files changed, 1020 insertions(+), 484 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc9328eefd..0b78bd6643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Dependencies + +- Bump Android SDK from v8.28.0 to v8.30.0 ([#3451](https://github.com/getsentry/sentry-dart/pull/3451)) + - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8300) + - [diff](https://github.com/getsentry/sentry-java/compare/8.28.0...8.30.0) + ## 9.10.0 ### Fixes diff --git a/packages/flutter/android/build.gradle b/packages/flutter/android/build.gradle index f71518ee1f..59dcf88099 100644 --- a/packages/flutter/android/build.gradle +++ b/packages/flutter/android/build.gradle @@ -62,7 +62,7 @@ android { } dependencies { - api 'io.sentry:sentry-android:8.28.0' + api 'io.sentry:sentry-android:8.30.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Required -- JUnit 4 framework diff --git a/packages/flutter/lib/src/native/java/binding.dart b/packages/flutter/lib/src/native/java/binding.dart index 1b495fced2..5a4868e3dd 100644 --- a/packages/flutter/lib/src/native/java/binding.dart +++ b/packages/flutter/lib/src/native/java/binding.dart @@ -699,6 +699,54 @@ class SentryAndroidOptions extends SentryOptions { .check(); } + static final _id_setTombstoneEnabled = _class.instanceMethodId( + r'setTombstoneEnabled', + r'(Z)V', + ); + + static final _setTombstoneEnabled = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setTombstoneEnabled(boolean z)` + void setTombstoneEnabled( + bool z, + ) { + _setTombstoneEnabled(reference.pointer, + _id_setTombstoneEnabled as jni$_.JMethodIDPtr, z ? 1 : 0) + .check(); + } + + static final _id_isTombstoneEnabled = _class.instanceMethodId( + r'isTombstoneEnabled', + r'()Z', + ); + + static final _isTombstoneEnabled = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isTombstoneEnabled()` + bool isTombstoneEnabled() { + return _isTombstoneEnabled( + reference.pointer, _id_isTombstoneEnabled as jni$_.JMethodIDPtr) + .boolean; + } + static final _id_isEnableActivityLifecycleBreadcrumbs = _class.instanceMethodId( r'isEnableActivityLifecycleBreadcrumbs', @@ -1287,6 +1335,57 @@ class SentryAndroidOptions extends SentryOptions { .check(); } + static final _id_isCollectExternalStorageContext = _class.instanceMethodId( + r'isCollectExternalStorageContext', + r'()Z', + ); + + static final _isCollectExternalStorageContext = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isCollectExternalStorageContext()` + bool isCollectExternalStorageContext() { + return _isCollectExternalStorageContext(reference.pointer, + _id_isCollectExternalStorageContext as jni$_.JMethodIDPtr) + .boolean; + } + + static final _id_setCollectExternalStorageContext = _class.instanceMethodId( + r'setCollectExternalStorageContext', + r'(Z)V', + ); + + static final _setCollectExternalStorageContext = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setCollectExternalStorageContext(boolean z)` + void setCollectExternalStorageContext( + bool z, + ) { + _setCollectExternalStorageContext( + reference.pointer, + _id_setCollectExternalStorageContext as jni$_.JMethodIDPtr, + z ? 1 : 0) + .check(); + } + static final _id_isEnableFramesTracking = _class.instanceMethodId( r'isEnableFramesTracking', r'()Z', @@ -1772,6 +1871,55 @@ class SentryAndroidOptions extends SentryOptions { .check(); } + static final _id_isReportHistoricalTombstones = _class.instanceMethodId( + r'isReportHistoricalTombstones', + r'()Z', + ); + + static final _isReportHistoricalTombstones = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isReportHistoricalTombstones()` + bool isReportHistoricalTombstones() { + return _isReportHistoricalTombstones(reference.pointer, + _id_isReportHistoricalTombstones as jni$_.JMethodIDPtr) + .boolean; + } + + static final _id_setReportHistoricalTombstones = _class.instanceMethodId( + r'setReportHistoricalTombstones', + r'(Z)V', + ); + + static final _setReportHistoricalTombstones = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setReportHistoricalTombstones(boolean z)` + void setReportHistoricalTombstones( + bool z, + ) { + _setReportHistoricalTombstones(reference.pointer, + _id_setReportHistoricalTombstones as jni$_.JMethodIDPtr, z ? 1 : 0) + .check(); + } + static final _id_isAttachAnrThreadDump = _class.instanceMethodId( r'isAttachAnrThreadDump', r'()Z', @@ -8164,6 +8312,30 @@ class Sentry extends jni$_.JObject { .object(const jni$_.JObjectType()); } + static final _id_metrics = _class.staticMethodId( + r'metrics', + r'()Lio/sentry/metrics/IMetricsApi;', + ); + + static final _metrics = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallStaticObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `static public io.sentry.metrics.IMetricsApi metrics()` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JObject metrics() { + return _metrics(_class.reference.pointer, _id_metrics as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + static final _id_showUserFeedbackDialog = _class.staticMethodId( r'showUserFeedbackDialog', r'()V', @@ -8607,62 +8779,62 @@ final class $SentryOptions$BeforeBreadcrumbCallback$Type } } -/// from: `io.sentry.SentryOptions$BeforeEmitMetricCallback` -class SentryOptions$BeforeEmitMetricCallback extends jni$_.JObject { +/// from: `io.sentry.SentryOptions$BeforeEnvelopeCallback` +class SentryOptions$BeforeEnvelopeCallback extends jni$_.JObject { @jni$_.internal @core$_.override - final jni$_.JObjType $type; + final jni$_.JObjType $type; @jni$_.internal - SentryOptions$BeforeEmitMetricCallback.fromReference( + SentryOptions$BeforeEnvelopeCallback.fromReference( jni$_.JReference reference, ) : $type = type, super.fromReference(reference); static final _class = - jni$_.JClass.forName(r'io/sentry/SentryOptions$BeforeEmitMetricCallback'); + jni$_.JClass.forName(r'io/sentry/SentryOptions$BeforeEnvelopeCallback'); /// The type which includes information such as the signature of this class. static const nullableType = - $SentryOptions$BeforeEmitMetricCallback$NullableType(); - static const type = $SentryOptions$BeforeEmitMetricCallback$Type(); + $SentryOptions$BeforeEnvelopeCallback$NullableType(); + static const type = $SentryOptions$BeforeEnvelopeCallback$Type(); static final _id_execute = _class.instanceMethodId( r'execute', - r'(Ljava/lang/String;Ljava/util/Map;)Z', + r'(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V', ); static final _execute = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract boolean execute(java.lang.String string, java.util.Map map)` - bool execute( - jni$_.JString string, - jni$_.JMap? map, + /// from: `public abstract void execute(io.sentry.SentryEnvelope sentryEnvelope, io.sentry.Hint hint)` + void execute( + jni$_.JObject sentryEnvelope, + Hint? hint, ) { - final _$string = string.reference; - final _$map = map?.reference ?? jni$_.jNullReference; - return _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr, - _$string.pointer, _$map.pointer) - .boolean; + final _$sentryEnvelope = sentryEnvelope.reference; + final _$hint = hint?.reference ?? jni$_.jNullReference; + _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr, + _$sentryEnvelope.pointer, _$hint.pointer) + .check(); } /// Maps a specific port to the implemented interface. - static final core$_.Map - _$impls = {}; + static final core$_.Map _$impls = + {}; static jni$_.JObjectPtr _$invoke( int port, jni$_.JObjectPtr descriptor, @@ -8691,15 +8863,12 @@ class SentryOptions$BeforeEmitMetricCallback extends jni$_.JObject { try { final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); final $a = $i.args; - if ($d == r'execute(Ljava/lang/String;Ljava/util/Map;)Z') { - final $r = _$impls[$p]!.execute( - $a![0]!.as(const jni$_.JStringType(), releaseOriginal: true), - $a![1]?.as( - const jni$_.JMapType( - jni$_.JStringNullableType(), jni$_.JStringNullableType()), - releaseOriginal: true), + if ($d == r'execute(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V') { + _$impls[$p]!.execute( + $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), + $a![1]?.as(const $Hint$Type(), releaseOriginal: true), ); - return jni$_.JBoolean($r).reference.toPointer(); + return jni$_.nullptr; } } catch (e) { return jni$_.ProtectedJniExtensions.newDartException(e); @@ -8709,7 +8878,7 @@ class SentryOptions$BeforeEmitMetricCallback extends jni$_.JObject { static void implementIn( jni$_.JImplementer implementer, - $SentryOptions$BeforeEmitMetricCallback $impl, + $SentryOptions$BeforeEnvelopeCallback $impl, ) { late final jni$_.RawReceivePort $p; $p = jni$_.RawReceivePort(($m) { @@ -8723,71 +8892,70 @@ class SentryOptions$BeforeEmitMetricCallback extends jni$_.JObject { jni$_.ProtectedJniExtensions.returnResult($i.result, $r); }); implementer.add( - r'io.sentry.SentryOptions$BeforeEmitMetricCallback', + r'io.sentry.SentryOptions$BeforeEnvelopeCallback', $p, _$invokePointer, - [], + [ + if ($impl.execute$async) + r'execute(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V', + ], ); final $a = $p.sendPort.nativePort; _$impls[$a] = $impl; } - factory SentryOptions$BeforeEmitMetricCallback.implement( - $SentryOptions$BeforeEmitMetricCallback $impl, + factory SentryOptions$BeforeEnvelopeCallback.implement( + $SentryOptions$BeforeEnvelopeCallback $impl, ) { final $i = jni$_.JImplementer(); implementIn($i, $impl); - return SentryOptions$BeforeEmitMetricCallback.fromReference( + return SentryOptions$BeforeEnvelopeCallback.fromReference( $i.implementReference(), ); } } -abstract base mixin class $SentryOptions$BeforeEmitMetricCallback { - factory $SentryOptions$BeforeEmitMetricCallback({ - required bool Function(jni$_.JString string, - jni$_.JMap? map) - execute, - }) = _$SentryOptions$BeforeEmitMetricCallback; +abstract base mixin class $SentryOptions$BeforeEnvelopeCallback { + factory $SentryOptions$BeforeEnvelopeCallback({ + required void Function(jni$_.JObject sentryEnvelope, Hint? hint) execute, + bool execute$async, + }) = _$SentryOptions$BeforeEnvelopeCallback; - bool execute( - jni$_.JString string, jni$_.JMap? map); + void execute(jni$_.JObject sentryEnvelope, Hint? hint); + bool get execute$async => false; } -final class _$SentryOptions$BeforeEmitMetricCallback - with $SentryOptions$BeforeEmitMetricCallback { - _$SentryOptions$BeforeEmitMetricCallback({ - required bool Function(jni$_.JString string, - jni$_.JMap? map) - execute, +final class _$SentryOptions$BeforeEnvelopeCallback + with $SentryOptions$BeforeEnvelopeCallback { + _$SentryOptions$BeforeEnvelopeCallback({ + required void Function(jni$_.JObject sentryEnvelope, Hint? hint) execute, + this.execute$async = false, }) : _execute = execute; - final bool Function( - jni$_.JString string, jni$_.JMap? map) - _execute; + final void Function(jni$_.JObject sentryEnvelope, Hint? hint) _execute; + final bool execute$async; - bool execute( - jni$_.JString string, jni$_.JMap? map) { - return _execute(string, map); + void execute(jni$_.JObject sentryEnvelope, Hint? hint) { + return _execute(sentryEnvelope, hint); } } -final class $SentryOptions$BeforeEmitMetricCallback$NullableType - extends jni$_.JObjType { +final class $SentryOptions$BeforeEnvelopeCallback$NullableType + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$BeforeEmitMetricCallback$NullableType(); + const $SentryOptions$BeforeEnvelopeCallback$NullableType(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$BeforeEmitMetricCallback;'; + String get signature => r'Lio/sentry/SentryOptions$BeforeEnvelopeCallback;'; @jni$_.internal @core$_.override - SentryOptions$BeforeEmitMetricCallback? fromReference( + SentryOptions$BeforeEnvelopeCallback? fromReference( jni$_.JReference reference) => reference.isNull ? null - : SentryOptions$BeforeEmitMetricCallback.fromReference( + : SentryOptions$BeforeEnvelopeCallback.fromReference( reference, ); @jni$_.internal @@ -8796,7 +8964,7 @@ final class $SentryOptions$BeforeEmitMetricCallback$NullableType @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => + jni$_.JObjType get nullableType => this; @jni$_.internal @@ -8805,30 +8973,30 @@ final class $SentryOptions$BeforeEmitMetricCallback$NullableType @core$_.override int get hashCode => - ($SentryOptions$BeforeEmitMetricCallback$NullableType).hashCode; + ($SentryOptions$BeforeEnvelopeCallback$NullableType).hashCode; @core$_.override bool operator ==(Object other) { return other.runtimeType == - ($SentryOptions$BeforeEmitMetricCallback$NullableType) && - other is $SentryOptions$BeforeEmitMetricCallback$NullableType; + ($SentryOptions$BeforeEnvelopeCallback$NullableType) && + other is $SentryOptions$BeforeEnvelopeCallback$NullableType; } } -final class $SentryOptions$BeforeEmitMetricCallback$Type - extends jni$_.JObjType { +final class $SentryOptions$BeforeEnvelopeCallback$Type + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$BeforeEmitMetricCallback$Type(); + const $SentryOptions$BeforeEnvelopeCallback$Type(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$BeforeEmitMetricCallback;'; + String get signature => r'Lio/sentry/SentryOptions$BeforeEnvelopeCallback;'; @jni$_.internal @core$_.override - SentryOptions$BeforeEmitMetricCallback fromReference( + SentryOptions$BeforeEnvelopeCallback fromReference( jni$_.JReference reference) => - SentryOptions$BeforeEmitMetricCallback.fromReference( + SentryOptions$BeforeEnvelopeCallback.fromReference( reference, ); @jni$_.internal @@ -8837,312 +9005,68 @@ final class $SentryOptions$BeforeEmitMetricCallback$Type @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => - const $SentryOptions$BeforeEmitMetricCallback$NullableType(); + jni$_.JObjType get nullableType => + const $SentryOptions$BeforeEnvelopeCallback$NullableType(); @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => ($SentryOptions$BeforeEmitMetricCallback$Type).hashCode; + int get hashCode => ($SentryOptions$BeforeEnvelopeCallback$Type).hashCode; @core$_.override bool operator ==(Object other) { - return other.runtimeType == - ($SentryOptions$BeforeEmitMetricCallback$Type) && - other is $SentryOptions$BeforeEmitMetricCallback$Type; + return other.runtimeType == ($SentryOptions$BeforeEnvelopeCallback$Type) && + other is $SentryOptions$BeforeEnvelopeCallback$Type; } } -/// from: `io.sentry.SentryOptions$BeforeEnvelopeCallback` -class SentryOptions$BeforeEnvelopeCallback extends jni$_.JObject { +/// from: `io.sentry.SentryOptions$BeforeSendCallback` +class SentryOptions$BeforeSendCallback extends jni$_.JObject { @jni$_.internal @core$_.override - final jni$_.JObjType $type; + final jni$_.JObjType $type; @jni$_.internal - SentryOptions$BeforeEnvelopeCallback.fromReference( + SentryOptions$BeforeSendCallback.fromReference( jni$_.JReference reference, ) : $type = type, super.fromReference(reference); static final _class = - jni$_.JClass.forName(r'io/sentry/SentryOptions$BeforeEnvelopeCallback'); + jni$_.JClass.forName(r'io/sentry/SentryOptions$BeforeSendCallback'); /// The type which includes information such as the signature of this class. - static const nullableType = - $SentryOptions$BeforeEnvelopeCallback$NullableType(); - static const type = $SentryOptions$BeforeEnvelopeCallback$Type(); + static const nullableType = $SentryOptions$BeforeSendCallback$NullableType(); + static const type = $SentryOptions$BeforeSendCallback$Type(); static final _id_execute = _class.instanceMethodId( r'execute', - r'(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V', + r'(Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;', ); static final _execute = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract void execute(io.sentry.SentryEnvelope sentryEnvelope, io.sentry.Hint hint)` - void execute( - jni$_.JObject sentryEnvelope, - Hint? hint, - ) { - final _$sentryEnvelope = sentryEnvelope.reference; - final _$hint = hint?.reference ?? jni$_.jNullReference; - _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr, - _$sentryEnvelope.pointer, _$hint.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'execute(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V') { - _$impls[$p]!.execute( - $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), - $a![1]?.as(const $Hint$Type(), releaseOriginal: true), - ); - return jni$_.nullptr; - } - } catch (e) { - return jni$_.ProtectedJniExtensions.newDartException(e); - } - return jni$_.nullptr; - } - - static void implementIn( - jni$_.JImplementer implementer, - $SentryOptions$BeforeEnvelopeCallback $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.SentryOptions$BeforeEnvelopeCallback', - $p, - _$invokePointer, - [ - if ($impl.execute$async) - r'execute(Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V', - ], - ); - final $a = $p.sendPort.nativePort; - _$impls[$a] = $impl; - } - - factory SentryOptions$BeforeEnvelopeCallback.implement( - $SentryOptions$BeforeEnvelopeCallback $impl, - ) { - final $i = jni$_.JImplementer(); - implementIn($i, $impl); - return SentryOptions$BeforeEnvelopeCallback.fromReference( - $i.implementReference(), - ); - } -} - -abstract base mixin class $SentryOptions$BeforeEnvelopeCallback { - factory $SentryOptions$BeforeEnvelopeCallback({ - required void Function(jni$_.JObject sentryEnvelope, Hint? hint) execute, - bool execute$async, - }) = _$SentryOptions$BeforeEnvelopeCallback; - - void execute(jni$_.JObject sentryEnvelope, Hint? hint); - bool get execute$async => false; -} - -final class _$SentryOptions$BeforeEnvelopeCallback - with $SentryOptions$BeforeEnvelopeCallback { - _$SentryOptions$BeforeEnvelopeCallback({ - required void Function(jni$_.JObject sentryEnvelope, Hint? hint) execute, - this.execute$async = false, - }) : _execute = execute; - - final void Function(jni$_.JObject sentryEnvelope, Hint? hint) _execute; - final bool execute$async; - - void execute(jni$_.JObject sentryEnvelope, Hint? hint) { - return _execute(sentryEnvelope, hint); - } -} - -final class $SentryOptions$BeforeEnvelopeCallback$NullableType - extends jni$_.JObjType { - @jni$_.internal - const $SentryOptions$BeforeEnvelopeCallback$NullableType(); - - @jni$_.internal - @core$_.override - String get signature => r'Lio/sentry/SentryOptions$BeforeEnvelopeCallback;'; - - @jni$_.internal - @core$_.override - SentryOptions$BeforeEnvelopeCallback? fromReference( - jni$_.JReference reference) => - reference.isNull - ? null - : SentryOptions$BeforeEnvelopeCallback.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 => - ($SentryOptions$BeforeEnvelopeCallback$NullableType).hashCode; - - @core$_.override - bool operator ==(Object other) { - return other.runtimeType == - ($SentryOptions$BeforeEnvelopeCallback$NullableType) && - other is $SentryOptions$BeforeEnvelopeCallback$NullableType; - } -} - -final class $SentryOptions$BeforeEnvelopeCallback$Type - extends jni$_.JObjType { - @jni$_.internal - const $SentryOptions$BeforeEnvelopeCallback$Type(); - - @jni$_.internal - @core$_.override - String get signature => r'Lio/sentry/SentryOptions$BeforeEnvelopeCallback;'; - - @jni$_.internal - @core$_.override - SentryOptions$BeforeEnvelopeCallback fromReference( - jni$_.JReference reference) => - SentryOptions$BeforeEnvelopeCallback.fromReference( - reference, - ); - @jni$_.internal - @core$_.override - jni$_.JObjType get superType => const jni$_.JObjectNullableType(); - - @jni$_.internal - @core$_.override - jni$_.JObjType get nullableType => - const $SentryOptions$BeforeEnvelopeCallback$NullableType(); - - @jni$_.internal - @core$_.override - final superCount = 1; - - @core$_.override - int get hashCode => ($SentryOptions$BeforeEnvelopeCallback$Type).hashCode; - - @core$_.override - bool operator ==(Object other) { - return other.runtimeType == ($SentryOptions$BeforeEnvelopeCallback$Type) && - other is $SentryOptions$BeforeEnvelopeCallback$Type; - } -} - -/// from: `io.sentry.SentryOptions$BeforeSendCallback` -class SentryOptions$BeforeSendCallback extends jni$_.JObject { - @jni$_.internal - @core$_.override - final jni$_.JObjType $type; - - @jni$_.internal - SentryOptions$BeforeSendCallback.fromReference( - jni$_.JReference reference, - ) : $type = type, - super.fromReference(reference); - - static final _class = - jni$_.JClass.forName(r'io/sentry/SentryOptions$BeforeSendCallback'); - - /// The type which includes information such as the signature of this class. - static const nullableType = $SentryOptions$BeforeSendCallback$NullableType(); - static const type = $SentryOptions$BeforeSendCallback$Type(); - static final _id_execute = _class.instanceMethodId( - r'execute', - r'(Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;', - ); - - static final _execute = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); - - /// from: `public abstract io.sentry.SentryEvent execute(io.sentry.SentryEvent sentryEvent, io.sentry.Hint hint)` - /// The returned object must be released after use, by calling the [release] method. - SentryEvent? execute( - SentryEvent sentryEvent, - Hint hint, + /// from: `public abstract io.sentry.SentryEvent execute(io.sentry.SentryEvent sentryEvent, io.sentry.Hint hint)` + /// The returned object must be released after use, by calling the [release] method. + SentryEvent? execute( + SentryEvent sentryEvent, + Hint hint, ) { final _$sentryEvent = sentryEvent.reference; final _$hint = hint.reference; @@ -10332,22 +10256,535 @@ class SentryOptions$DistributionOptions extends jni$_.JObject { } } -final class $SentryOptions$DistributionOptions$NullableType - extends jni$_.JObjType { +final class $SentryOptions$DistributionOptions$NullableType + extends jni$_.JObjType { + @jni$_.internal + const $SentryOptions$DistributionOptions$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/SentryOptions$DistributionOptions;'; + + @jni$_.internal + @core$_.override + SentryOptions$DistributionOptions? fromReference( + jni$_.JReference reference) => + reference.isNull + ? null + : SentryOptions$DistributionOptions.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 => + ($SentryOptions$DistributionOptions$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == + ($SentryOptions$DistributionOptions$NullableType) && + other is $SentryOptions$DistributionOptions$NullableType; + } +} + +final class $SentryOptions$DistributionOptions$Type + extends jni$_.JObjType { + @jni$_.internal + const $SentryOptions$DistributionOptions$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/SentryOptions$DistributionOptions;'; + + @jni$_.internal + @core$_.override + SentryOptions$DistributionOptions fromReference(jni$_.JReference reference) => + SentryOptions$DistributionOptions.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $SentryOptions$DistributionOptions$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($SentryOptions$DistributionOptions$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($SentryOptions$DistributionOptions$Type) && + other is $SentryOptions$DistributionOptions$Type; + } +} + +/// from: `io.sentry.SentryOptions$Logs$BeforeSendLogCallback` +class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + SentryOptions$Logs$BeforeSendLogCallback.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = jni$_.JClass.forName( + r'io/sentry/SentryOptions$Logs$BeforeSendLogCallback'); + + /// The type which includes information such as the signature of this class. + static const nullableType = + $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); + static const type = $SentryOptions$Logs$BeforeSendLogCallback$Type(); + static final _id_execute = _class.instanceMethodId( + r'execute', + r'(Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent;', + ); + + static final _execute = 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 abstract io.sentry.SentryLogEvent execute(io.sentry.SentryLogEvent sentryLogEvent)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? execute( + jni$_.JObject sentryLogEvent, + ) { + final _$sentryLogEvent = sentryLogEvent.reference; + return _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr, + _$sentryLogEvent.pointer) + .object(const jni$_.JObjectNullableType()); + } + + /// 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'execute(Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent;') { + final $r = _$impls[$p]!.execute( + $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), + ); + return ($r as jni$_.JObject?) + ?.as(const jni$_.JObjectType()) + .reference + .toPointer() ?? + jni$_.nullptr; + } + } catch (e) { + return jni$_.ProtectedJniExtensions.newDartException(e); + } + return jni$_.nullptr; + } + + static void implementIn( + jni$_.JImplementer implementer, + $SentryOptions$Logs$BeforeSendLogCallback $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.SentryOptions$Logs$BeforeSendLogCallback', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory SentryOptions$Logs$BeforeSendLogCallback.implement( + $SentryOptions$Logs$BeforeSendLogCallback $impl, + ) { + final $i = jni$_.JImplementer(); + implementIn($i, $impl); + return SentryOptions$Logs$BeforeSendLogCallback.fromReference( + $i.implementReference(), + ); + } +} + +abstract base mixin class $SentryOptions$Logs$BeforeSendLogCallback { + factory $SentryOptions$Logs$BeforeSendLogCallback({ + required jni$_.JObject? Function(jni$_.JObject sentryLogEvent) execute, + }) = _$SentryOptions$Logs$BeforeSendLogCallback; + + jni$_.JObject? execute(jni$_.JObject sentryLogEvent); +} + +final class _$SentryOptions$Logs$BeforeSendLogCallback + with $SentryOptions$Logs$BeforeSendLogCallback { + _$SentryOptions$Logs$BeforeSendLogCallback({ + required jni$_.JObject? Function(jni$_.JObject sentryLogEvent) execute, + }) : _execute = execute; + + final jni$_.JObject? Function(jni$_.JObject sentryLogEvent) _execute; + + jni$_.JObject? execute(jni$_.JObject sentryLogEvent) { + return _execute(sentryLogEvent); + } +} + +final class $SentryOptions$Logs$BeforeSendLogCallback$NullableType + extends jni$_.JObjType { + @jni$_.internal + const $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => + r'Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;'; + + @jni$_.internal + @core$_.override + SentryOptions$Logs$BeforeSendLogCallback? fromReference( + jni$_.JReference reference) => + reference.isNull + ? null + : SentryOptions$Logs$BeforeSendLogCallback.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 => + ($SentryOptions$Logs$BeforeSendLogCallback$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == + ($SentryOptions$Logs$BeforeSendLogCallback$NullableType) && + other is $SentryOptions$Logs$BeforeSendLogCallback$NullableType; + } +} + +final class $SentryOptions$Logs$BeforeSendLogCallback$Type + extends jni$_.JObjType { + @jni$_.internal + const $SentryOptions$Logs$BeforeSendLogCallback$Type(); + + @jni$_.internal + @core$_.override + String get signature => + r'Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;'; + + @jni$_.internal + @core$_.override + SentryOptions$Logs$BeforeSendLogCallback fromReference( + jni$_.JReference reference) => + SentryOptions$Logs$BeforeSendLogCallback.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($SentryOptions$Logs$BeforeSendLogCallback$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == + ($SentryOptions$Logs$BeforeSendLogCallback$Type) && + other is $SentryOptions$Logs$BeforeSendLogCallback$Type; + } +} + +/// from: `io.sentry.SentryOptions$Logs` +class SentryOptions$Logs extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + SentryOptions$Logs.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = jni$_.JClass.forName(r'io/sentry/SentryOptions$Logs'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $SentryOptions$Logs$NullableType(); + static const type = $SentryOptions$Logs$Type(); + static final _id_new$ = _class.constructorId( + r'()V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public void ()` + /// The returned object must be released after use, by calling the [release] method. + factory SentryOptions$Logs() { + return SentryOptions$Logs.fromReference( + _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) + .reference); + } + + static final _id_isEnabled = _class.instanceMethodId( + r'isEnabled', + r'()Z', + ); + + static final _isEnabled = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isEnabled()` + bool isEnabled() { + return _isEnabled(reference.pointer, _id_isEnabled as jni$_.JMethodIDPtr) + .boolean; + } + + static final _id_setEnabled = _class.instanceMethodId( + r'setEnabled', + r'(Z)V', + ); + + static final _setEnabled = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setEnabled(boolean z)` + void setEnabled( + bool z, + ) { + _setEnabled( + reference.pointer, _id_setEnabled as jni$_.JMethodIDPtr, z ? 1 : 0) + .check(); + } + + static final _id_getBeforeSend = _class.instanceMethodId( + r'getBeforeSend', + r'()Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;', + ); + + static final _getBeforeSend = 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$Logs$BeforeSendLogCallback getBeforeSend()` + /// The returned object must be released after use, by calling the [release] method. + SentryOptions$Logs$BeforeSendLogCallback? getBeforeSend() { + return _getBeforeSend( + reference.pointer, _id_getBeforeSend as jni$_.JMethodIDPtr) + .object( + const $SentryOptions$Logs$BeforeSendLogCallback$NullableType()); + } + + static final _id_setBeforeSend = _class.instanceMethodId( + r'setBeforeSend', + r'(Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;)V', + ); + + static final _setBeforeSend = 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 setBeforeSend(io.sentry.SentryOptions$Logs$BeforeSendLogCallback beforeSendLogCallback)` + void setBeforeSend( + SentryOptions$Logs$BeforeSendLogCallback? beforeSendLogCallback, + ) { + final _$beforeSendLogCallback = + beforeSendLogCallback?.reference ?? jni$_.jNullReference; + _setBeforeSend(reference.pointer, _id_setBeforeSend as jni$_.JMethodIDPtr, + _$beforeSendLogCallback.pointer) + .check(); + } + + static final _id_getLoggerBatchProcessorFactory = _class.instanceMethodId( + r'getLoggerBatchProcessorFactory', + r'()Lio/sentry/logger/ILoggerBatchProcessorFactory;', + ); + + static final _getLoggerBatchProcessorFactory = + 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.logger.ILoggerBatchProcessorFactory getLoggerBatchProcessorFactory()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getLoggerBatchProcessorFactory() { + return _getLoggerBatchProcessorFactory(reference.pointer, + _id_getLoggerBatchProcessorFactory as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_setLoggerBatchProcessorFactory = _class.instanceMethodId( + r'setLoggerBatchProcessorFactory', + r'(Lio/sentry/logger/ILoggerBatchProcessorFactory;)V', + ); + + static final _setLoggerBatchProcessorFactory = + 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 setLoggerBatchProcessorFactory(io.sentry.logger.ILoggerBatchProcessorFactory iLoggerBatchProcessorFactory)` + void setLoggerBatchProcessorFactory( + jni$_.JObject iLoggerBatchProcessorFactory, + ) { + final _$iLoggerBatchProcessorFactory = + iLoggerBatchProcessorFactory.reference; + _setLoggerBatchProcessorFactory( + reference.pointer, + _id_setLoggerBatchProcessorFactory as jni$_.JMethodIDPtr, + _$iLoggerBatchProcessorFactory.pointer) + .check(); + } +} + +final class $SentryOptions$Logs$NullableType + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$DistributionOptions$NullableType(); + const $SentryOptions$Logs$NullableType(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$DistributionOptions;'; + String get signature => r'Lio/sentry/SentryOptions$Logs;'; @jni$_.internal @core$_.override - SentryOptions$DistributionOptions? fromReference( - jni$_.JReference reference) => + SentryOptions$Logs? fromReference(jni$_.JReference reference) => reference.isNull ? null - : SentryOptions$DistributionOptions.fromReference( + : SentryOptions$Logs.fromReference( reference, ); @jni$_.internal @@ -10356,37 +10793,35 @@ final class $SentryOptions$DistributionOptions$NullableType @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => this; + jni$_.JObjType get nullableType => this; @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => - ($SentryOptions$DistributionOptions$NullableType).hashCode; + int get hashCode => ($SentryOptions$Logs$NullableType).hashCode; @core$_.override bool operator ==(Object other) { - return other.runtimeType == - ($SentryOptions$DistributionOptions$NullableType) && - other is $SentryOptions$DistributionOptions$NullableType; + return other.runtimeType == ($SentryOptions$Logs$NullableType) && + other is $SentryOptions$Logs$NullableType; } } -final class $SentryOptions$DistributionOptions$Type - extends jni$_.JObjType { +final class $SentryOptions$Logs$Type + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$DistributionOptions$Type(); + const $SentryOptions$Logs$Type(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$DistributionOptions;'; + String get signature => r'Lio/sentry/SentryOptions$Logs;'; @jni$_.internal @core$_.override - SentryOptions$DistributionOptions fromReference(jni$_.JReference reference) => - SentryOptions$DistributionOptions.fromReference( + SentryOptions$Logs fromReference(jni$_.JReference reference) => + SentryOptions$Logs.fromReference( reference, ); @jni$_.internal @@ -10395,71 +10830,79 @@ final class $SentryOptions$DistributionOptions$Type @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => - const $SentryOptions$DistributionOptions$NullableType(); + jni$_.JObjType get nullableType => + const $SentryOptions$Logs$NullableType(); @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => ($SentryOptions$DistributionOptions$Type).hashCode; + int get hashCode => ($SentryOptions$Logs$Type).hashCode; @core$_.override bool operator ==(Object other) { - return other.runtimeType == ($SentryOptions$DistributionOptions$Type) && - other is $SentryOptions$DistributionOptions$Type; + return other.runtimeType == ($SentryOptions$Logs$Type) && + other is $SentryOptions$Logs$Type; } } -/// from: `io.sentry.SentryOptions$Logs$BeforeSendLogCallback` -class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { +/// from: `io.sentry.SentryOptions$Metrics$BeforeSendMetricCallback` +class SentryOptions$Metrics$BeforeSendMetricCallback extends jni$_.JObject { @jni$_.internal @core$_.override - final jni$_.JObjType $type; + final jni$_.JObjType $type; @jni$_.internal - SentryOptions$Logs$BeforeSendLogCallback.fromReference( + SentryOptions$Metrics$BeforeSendMetricCallback.fromReference( jni$_.JReference reference, ) : $type = type, super.fromReference(reference); static final _class = jni$_.JClass.forName( - r'io/sentry/SentryOptions$Logs$BeforeSendLogCallback'); + r'io/sentry/SentryOptions$Metrics$BeforeSendMetricCallback'); /// The type which includes information such as the signature of this class. static const nullableType = - $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); - static const type = $SentryOptions$Logs$BeforeSendLogCallback$Type(); + $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType(); + static const type = $SentryOptions$Metrics$BeforeSendMetricCallback$Type(); static final _id_execute = _class.instanceMethodId( r'execute', - r'(Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent;', + r'(Lio/sentry/SentryMetricsEvent;Lio/sentry/Hint;)Lio/sentry/SentryMetricsEvent;', ); static final _execute = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract io.sentry.SentryLogEvent execute(io.sentry.SentryLogEvent sentryLogEvent)` + /// from: `public abstract io.sentry.SentryMetricsEvent execute(io.sentry.SentryMetricsEvent sentryMetricsEvent, io.sentry.Hint hint)` /// The returned object must be released after use, by calling the [release] method. jni$_.JObject? execute( - jni$_.JObject sentryLogEvent, + jni$_.JObject sentryMetricsEvent, + Hint hint, ) { - final _$sentryLogEvent = sentryLogEvent.reference; + final _$sentryMetricsEvent = sentryMetricsEvent.reference; + final _$hint = hint.reference; return _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr, - _$sentryLogEvent.pointer) + _$sentryMetricsEvent.pointer, _$hint.pointer) .object(const jni$_.JObjectNullableType()); } /// Maps a specific port to the implemented interface. - static final core$_.Map + static final core$_.Map _$impls = {}; static jni$_.JObjectPtr _$invoke( int port, @@ -10490,9 +10933,10 @@ class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); final $a = $i.args; if ($d == - r'execute(Lio/sentry/SentryLogEvent;)Lio/sentry/SentryLogEvent;') { + r'execute(Lio/sentry/SentryMetricsEvent;Lio/sentry/Hint;)Lio/sentry/SentryMetricsEvent;') { final $r = _$impls[$p]!.execute( $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true), + $a![1]!.as(const $Hint$Type(), releaseOriginal: true), ); return ($r as jni$_.JObject?) ?.as(const jni$_.JObjectType()) @@ -10508,7 +10952,7 @@ class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { static void implementIn( jni$_.JImplementer implementer, - $SentryOptions$Logs$BeforeSendLogCallback $impl, + $SentryOptions$Metrics$BeforeSendMetricCallback $impl, ) { late final jni$_.RawReceivePort $p; $p = jni$_.RawReceivePort(($m) { @@ -10522,7 +10966,7 @@ class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { jni$_.ProtectedJniExtensions.returnResult($i.result, $r); }); implementer.add( - r'io.sentry.SentryOptions$Logs$BeforeSendLogCallback', + r'io.sentry.SentryOptions$Metrics$BeforeSendMetricCallback', $p, _$invokePointer, [], @@ -10531,55 +10975,60 @@ class SentryOptions$Logs$BeforeSendLogCallback extends jni$_.JObject { _$impls[$a] = $impl; } - factory SentryOptions$Logs$BeforeSendLogCallback.implement( - $SentryOptions$Logs$BeforeSendLogCallback $impl, + factory SentryOptions$Metrics$BeforeSendMetricCallback.implement( + $SentryOptions$Metrics$BeforeSendMetricCallback $impl, ) { final $i = jni$_.JImplementer(); implementIn($i, $impl); - return SentryOptions$Logs$BeforeSendLogCallback.fromReference( + return SentryOptions$Metrics$BeforeSendMetricCallback.fromReference( $i.implementReference(), ); } } -abstract base mixin class $SentryOptions$Logs$BeforeSendLogCallback { - factory $SentryOptions$Logs$BeforeSendLogCallback({ - required jni$_.JObject? Function(jni$_.JObject sentryLogEvent) execute, - }) = _$SentryOptions$Logs$BeforeSendLogCallback; +abstract base mixin class $SentryOptions$Metrics$BeforeSendMetricCallback { + factory $SentryOptions$Metrics$BeforeSendMetricCallback({ + required jni$_.JObject? Function( + jni$_.JObject sentryMetricsEvent, Hint hint) + execute, + }) = _$SentryOptions$Metrics$BeforeSendMetricCallback; - jni$_.JObject? execute(jni$_.JObject sentryLogEvent); + jni$_.JObject? execute(jni$_.JObject sentryMetricsEvent, Hint hint); } -final class _$SentryOptions$Logs$BeforeSendLogCallback - with $SentryOptions$Logs$BeforeSendLogCallback { - _$SentryOptions$Logs$BeforeSendLogCallback({ - required jni$_.JObject? Function(jni$_.JObject sentryLogEvent) execute, +final class _$SentryOptions$Metrics$BeforeSendMetricCallback + with $SentryOptions$Metrics$BeforeSendMetricCallback { + _$SentryOptions$Metrics$BeforeSendMetricCallback({ + required jni$_.JObject? Function( + jni$_.JObject sentryMetricsEvent, Hint hint) + execute, }) : _execute = execute; - final jni$_.JObject? Function(jni$_.JObject sentryLogEvent) _execute; + final jni$_.JObject? Function(jni$_.JObject sentryMetricsEvent, Hint hint) + _execute; - jni$_.JObject? execute(jni$_.JObject sentryLogEvent) { - return _execute(sentryLogEvent); + jni$_.JObject? execute(jni$_.JObject sentryMetricsEvent, Hint hint) { + return _execute(sentryMetricsEvent, hint); } } -final class $SentryOptions$Logs$BeforeSendLogCallback$NullableType - extends jni$_.JObjType { +final class $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); + const $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType(); @jni$_.internal @core$_.override String get signature => - r'Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;'; + r'Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;'; @jni$_.internal @core$_.override - SentryOptions$Logs$BeforeSendLogCallback? fromReference( + SentryOptions$Metrics$BeforeSendMetricCallback? fromReference( jni$_.JReference reference) => reference.isNull ? null - : SentryOptions$Logs$BeforeSendLogCallback.fromReference( + : SentryOptions$Metrics$BeforeSendMetricCallback.fromReference( reference, ); @jni$_.internal @@ -10588,8 +11037,8 @@ final class $SentryOptions$Logs$BeforeSendLogCallback$NullableType @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => - this; + jni$_.JObjType + get nullableType => this; @jni$_.internal @core$_.override @@ -10597,31 +11046,31 @@ final class $SentryOptions$Logs$BeforeSendLogCallback$NullableType @core$_.override int get hashCode => - ($SentryOptions$Logs$BeforeSendLogCallback$NullableType).hashCode; + ($SentryOptions$Metrics$BeforeSendMetricCallback$NullableType).hashCode; @core$_.override bool operator ==(Object other) { return other.runtimeType == - ($SentryOptions$Logs$BeforeSendLogCallback$NullableType) && - other is $SentryOptions$Logs$BeforeSendLogCallback$NullableType; + ($SentryOptions$Metrics$BeforeSendMetricCallback$NullableType) && + other is $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType; } } -final class $SentryOptions$Logs$BeforeSendLogCallback$Type - extends jni$_.JObjType { +final class $SentryOptions$Metrics$BeforeSendMetricCallback$Type + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$Logs$BeforeSendLogCallback$Type(); + const $SentryOptions$Metrics$BeforeSendMetricCallback$Type(); @jni$_.internal @core$_.override String get signature => - r'Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;'; + r'Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;'; @jni$_.internal @core$_.override - SentryOptions$Logs$BeforeSendLogCallback fromReference( + SentryOptions$Metrics$BeforeSendMetricCallback fromReference( jni$_.JReference reference) => - SentryOptions$Logs$BeforeSendLogCallback.fromReference( + SentryOptions$Metrics$BeforeSendMetricCallback.fromReference( reference, ); @jni$_.internal @@ -10630,41 +11079,44 @@ final class $SentryOptions$Logs$BeforeSendLogCallback$Type @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => - const $SentryOptions$Logs$BeforeSendLogCallback$NullableType(); + jni$_.JObjType + get nullableType => + const $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType(); @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => ($SentryOptions$Logs$BeforeSendLogCallback$Type).hashCode; + int get hashCode => + ($SentryOptions$Metrics$BeforeSendMetricCallback$Type).hashCode; @core$_.override bool operator ==(Object other) { return other.runtimeType == - ($SentryOptions$Logs$BeforeSendLogCallback$Type) && - other is $SentryOptions$Logs$BeforeSendLogCallback$Type; + ($SentryOptions$Metrics$BeforeSendMetricCallback$Type) && + other is $SentryOptions$Metrics$BeforeSendMetricCallback$Type; } } -/// from: `io.sentry.SentryOptions$Logs` -class SentryOptions$Logs extends jni$_.JObject { +/// from: `io.sentry.SentryOptions$Metrics` +class SentryOptions$Metrics extends jni$_.JObject { @jni$_.internal @core$_.override - final jni$_.JObjType $type; + final jni$_.JObjType $type; @jni$_.internal - SentryOptions$Logs.fromReference( + SentryOptions$Metrics.fromReference( jni$_.JReference reference, ) : $type = type, super.fromReference(reference); - static final _class = jni$_.JClass.forName(r'io/sentry/SentryOptions$Logs'); + static final _class = + jni$_.JClass.forName(r'io/sentry/SentryOptions$Metrics'); /// The type which includes information such as the signature of this class. - static const nullableType = $SentryOptions$Logs$NullableType(); - static const type = $SentryOptions$Logs$Type(); + static const nullableType = $SentryOptions$Metrics$NullableType(); + static const type = $SentryOptions$Metrics$Type(); static final _id_new$ = _class.constructorId( r'()V', ); @@ -10683,8 +11135,8 @@ class SentryOptions$Logs extends jni$_.JObject { /// from: `public void ()` /// The returned object must be released after use, by calling the [release] method. - factory SentryOptions$Logs() { - return SentryOptions$Logs.fromReference( + factory SentryOptions$Metrics() { + return SentryOptions$Metrics.fromReference( _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr) .reference); } @@ -10738,7 +11190,7 @@ class SentryOptions$Logs extends jni$_.JObject { static final _id_getBeforeSend = _class.instanceMethodId( r'getBeforeSend', - r'()Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;', + r'()Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;', ); static final _getBeforeSend = jni$_.ProtectedJniExtensions.lookup< @@ -10753,18 +11205,18 @@ class SentryOptions$Logs extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public io.sentry.SentryOptions$Logs$BeforeSendLogCallback getBeforeSend()` + /// from: `public io.sentry.SentryOptions$Metrics$BeforeSendMetricCallback getBeforeSend()` /// The returned object must be released after use, by calling the [release] method. - SentryOptions$Logs$BeforeSendLogCallback? getBeforeSend() { + SentryOptions$Metrics$BeforeSendMetricCallback? getBeforeSend() { return _getBeforeSend( reference.pointer, _id_getBeforeSend as jni$_.JMethodIDPtr) - .object( - const $SentryOptions$Logs$BeforeSendLogCallback$NullableType()); + .object( + const $SentryOptions$Metrics$BeforeSendMetricCallback$NullableType()); } static final _id_setBeforeSend = _class.instanceMethodId( r'setBeforeSend', - r'(Lio/sentry/SentryOptions$Logs$BeforeSendLogCallback;)V', + r'(Lio/sentry/SentryOptions$Metrics$BeforeSendMetricCallback;)V', ); static final _setBeforeSend = jni$_.ProtectedJniExtensions.lookup< @@ -10778,23 +11230,23 @@ class SentryOptions$Logs extends jni$_.JObject { jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void setBeforeSend(io.sentry.SentryOptions$Logs$BeforeSendLogCallback beforeSendLogCallback)` + /// from: `public void setBeforeSend(io.sentry.SentryOptions$Metrics$BeforeSendMetricCallback beforeSendMetricCallback)` void setBeforeSend( - SentryOptions$Logs$BeforeSendLogCallback? beforeSendLogCallback, + SentryOptions$Metrics$BeforeSendMetricCallback? beforeSendMetricCallback, ) { - final _$beforeSendLogCallback = - beforeSendLogCallback?.reference ?? jni$_.jNullReference; + final _$beforeSendMetricCallback = + beforeSendMetricCallback?.reference ?? jni$_.jNullReference; _setBeforeSend(reference.pointer, _id_setBeforeSend as jni$_.JMethodIDPtr, - _$beforeSendLogCallback.pointer) + _$beforeSendMetricCallback.pointer) .check(); } - static final _id_getLoggerBatchProcessorFactory = _class.instanceMethodId( - r'getLoggerBatchProcessorFactory', - r'()Lio/sentry/logger/ILoggerBatchProcessorFactory;', + static final _id_getMetricsBatchProcessorFactory = _class.instanceMethodId( + r'getMetricsBatchProcessorFactory', + r'()Lio/sentry/metrics/IMetricsBatchProcessorFactory;', ); - static final _getLoggerBatchProcessorFactory = + static final _getMetricsBatchProcessorFactory = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( @@ -10807,20 +11259,20 @@ class SentryOptions$Logs extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public io.sentry.logger.ILoggerBatchProcessorFactory getLoggerBatchProcessorFactory()` + /// from: `public io.sentry.metrics.IMetricsBatchProcessorFactory getMetricsBatchProcessorFactory()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject getLoggerBatchProcessorFactory() { - return _getLoggerBatchProcessorFactory(reference.pointer, - _id_getLoggerBatchProcessorFactory as jni$_.JMethodIDPtr) + jni$_.JObject getMetricsBatchProcessorFactory() { + return _getMetricsBatchProcessorFactory(reference.pointer, + _id_getMetricsBatchProcessorFactory as jni$_.JMethodIDPtr) .object(const jni$_.JObjectType()); } - static final _id_setLoggerBatchProcessorFactory = _class.instanceMethodId( - r'setLoggerBatchProcessorFactory', - r'(Lio/sentry/logger/ILoggerBatchProcessorFactory;)V', + static final _id_setMetricsBatchProcessorFactory = _class.instanceMethodId( + r'setMetricsBatchProcessorFactory', + r'(Lio/sentry/metrics/IMetricsBatchProcessorFactory;)V', ); - static final _setLoggerBatchProcessorFactory = + static final _setMetricsBatchProcessorFactory = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( @@ -10832,35 +11284,35 @@ class SentryOptions$Logs extends jni$_.JObject { jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void setLoggerBatchProcessorFactory(io.sentry.logger.ILoggerBatchProcessorFactory iLoggerBatchProcessorFactory)` - void setLoggerBatchProcessorFactory( - jni$_.JObject iLoggerBatchProcessorFactory, + /// from: `public void setMetricsBatchProcessorFactory(io.sentry.metrics.IMetricsBatchProcessorFactory iMetricsBatchProcessorFactory)` + void setMetricsBatchProcessorFactory( + jni$_.JObject iMetricsBatchProcessorFactory, ) { - final _$iLoggerBatchProcessorFactory = - iLoggerBatchProcessorFactory.reference; - _setLoggerBatchProcessorFactory( + final _$iMetricsBatchProcessorFactory = + iMetricsBatchProcessorFactory.reference; + _setMetricsBatchProcessorFactory( reference.pointer, - _id_setLoggerBatchProcessorFactory as jni$_.JMethodIDPtr, - _$iLoggerBatchProcessorFactory.pointer) + _id_setMetricsBatchProcessorFactory as jni$_.JMethodIDPtr, + _$iMetricsBatchProcessorFactory.pointer) .check(); } } -final class $SentryOptions$Logs$NullableType - extends jni$_.JObjType { +final class $SentryOptions$Metrics$NullableType + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$Logs$NullableType(); + const $SentryOptions$Metrics$NullableType(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$Logs;'; + String get signature => r'Lio/sentry/SentryOptions$Metrics;'; @jni$_.internal @core$_.override - SentryOptions$Logs? fromReference(jni$_.JReference reference) => + SentryOptions$Metrics? fromReference(jni$_.JReference reference) => reference.isNull ? null - : SentryOptions$Logs.fromReference( + : SentryOptions$Metrics.fromReference( reference, ); @jni$_.internal @@ -10869,35 +11321,35 @@ final class $SentryOptions$Logs$NullableType @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => this; + jni$_.JObjType get nullableType => this; @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => ($SentryOptions$Logs$NullableType).hashCode; + int get hashCode => ($SentryOptions$Metrics$NullableType).hashCode; @core$_.override bool operator ==(Object other) { - return other.runtimeType == ($SentryOptions$Logs$NullableType) && - other is $SentryOptions$Logs$NullableType; + return other.runtimeType == ($SentryOptions$Metrics$NullableType) && + other is $SentryOptions$Metrics$NullableType; } } -final class $SentryOptions$Logs$Type - extends jni$_.JObjType { +final class $SentryOptions$Metrics$Type + extends jni$_.JObjType { @jni$_.internal - const $SentryOptions$Logs$Type(); + const $SentryOptions$Metrics$Type(); @jni$_.internal @core$_.override - String get signature => r'Lio/sentry/SentryOptions$Logs;'; + String get signature => r'Lio/sentry/SentryOptions$Metrics;'; @jni$_.internal @core$_.override - SentryOptions$Logs fromReference(jni$_.JReference reference) => - SentryOptions$Logs.fromReference( + SentryOptions$Metrics fromReference(jni$_.JReference reference) => + SentryOptions$Metrics.fromReference( reference, ); @jni$_.internal @@ -10906,20 +11358,20 @@ final class $SentryOptions$Logs$Type @jni$_.internal @core$_.override - jni$_.JObjType get nullableType => - const $SentryOptions$Logs$NullableType(); + jni$_.JObjType get nullableType => + const $SentryOptions$Metrics$NullableType(); @jni$_.internal @core$_.override final superCount = 1; @core$_.override - int get hashCode => ($SentryOptions$Logs$Type).hashCode; + int get hashCode => ($SentryOptions$Metrics$Type).hashCode; @core$_.override bool operator ==(Object other) { - return other.runtimeType == ($SentryOptions$Logs$Type) && - other is $SentryOptions$Logs$Type; + return other.runtimeType == ($SentryOptions$Metrics$Type) && + other is $SentryOptions$Metrics$Type; } } @@ -12643,6 +13095,8 @@ class SentryOptions extends jni$_.JObject { static jni$_.JString get DEFAULT_PROPAGATION_TARGETS => _id_DEFAULT_PROPAGATION_TARGETS.get(_class, const jni$_.JStringType()); + /// from: `static public final long MAX_EVENT_SIZE_BYTES` + static const MAX_EVENT_SIZE_BYTES = 1048576; static final _id_getProfilerConverter = _class.instanceMethodId( r'getProfilerConverter', r'()Lio/sentry/IProfileConverter;', @@ -19681,6 +20135,56 @@ class SentryOptions extends jni$_.JObject { .check(); } + static final _id_getMetrics = _class.instanceMethodId( + r'getMetrics', + r'()Lio/sentry/SentryOptions$Metrics;', + ); + + static final _getMetrics = 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$Metrics getMetrics()` + /// The returned object must be released after use, by calling the [release] method. + SentryOptions$Metrics getMetrics() { + return _getMetrics(reference.pointer, _id_getMetrics as jni$_.JMethodIDPtr) + .object(const $SentryOptions$Metrics$Type()); + } + + static final _id_setMetrics = _class.instanceMethodId( + r'setMetrics', + r'(Lio/sentry/SentryOptions$Metrics;)V', + ); + + static final _setMetrics = 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 setMetrics(io.sentry.SentryOptions$Metrics metrics)` + void setMetrics( + SentryOptions$Metrics metrics, + ) { + final _$metrics = metrics.reference; + _setMetrics(reference.pointer, _id_setMetrics as jni$_.JMethodIDPtr, + _$metrics.pointer) + .check(); + } + static final _id_getDistribution = _class.instanceMethodId( r'getDistribution', r'()Lio/sentry/SentryOptions$DistributionOptions;', @@ -31098,6 +31602,30 @@ class ScopesAdapter extends jni$_.JObject { .object(const jni$_.JObjectType()); } + static final _id_metrics = _class.instanceMethodId( + r'metrics', + r'()Lio/sentry/metrics/IMetricsApi;', + ); + + static final _metrics = 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.metrics.IMetricsApi metrics()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject metrics() { + return _metrics(reference.pointer, _id_metrics as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + static final _id_addFeatureFlag = _class.instanceMethodId( r'addFeatureFlag', r'(Ljava/lang/String;Ljava/lang/Boolean;)V', From e174634b8b0f1d4a58828c483081181ae8d37e87 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 22 Jan 2026 13:25:06 +0100 Subject: [PATCH 25/62] feat: trace connected metrics (#3450) Adds trace connected metrics feature to Dart --------- Co-authored-by: Claude Sonnet 4.5 --- CHANGELOG.md | 9 + packages/dart/lib/sentry.dart | 1 + .../src/client_reports/discarded_event.dart | 2 + packages/dart/lib/src/constants.dart | 77 ++ packages/dart/lib/src/hub.dart | 32 + packages/dart/lib/src/hub_adapter.dart | 5 + packages/dart/lib/src/noop_hub.dart | 4 + packages/dart/lib/src/noop_sentry_client.dart | 4 + .../dart/lib/src/sdk_lifecycle_hooks.dart | 7 + packages/dart/lib/src/sentry.dart | 5 + packages/dart/lib/src/sentry_client.dart | 14 +- packages/dart/lib/src/sentry_envelope.dart | 61 +- .../dart/lib/src/sentry_envelope_item.dart | 16 + packages/dart/lib/src/sentry_item_type.dart | 1 + packages/dart/lib/src/sentry_logger.dart | 44 +- packages/dart/lib/src/sentry_options.dart | 18 + .../lib/src/telemetry/default_attributes.dart | 55 + .../src/telemetry/metric/default_metrics.dart | 92 ++ .../dart/lib/src/telemetry/metric/metric.dart | 182 ++++ .../metric/metric_capture_pipeline.dart | 72 ++ .../lib/src/telemetry/metric/metrics.dart | 80 ++ .../metric/metrics_setup_integration.dart | 32 + .../src/telemetry/metric/noop_metrics.dart | 28 + .../src/telemetry/processing/processor.dart | 41 +- .../processing/processor_integration.dart | 16 +- .../dart/lib/src/telemetry/telemetry.dart | 2 + .../dart/lib/src/transport/data_category.dart | 3 + .../lib/src/transport/rate_limit_parser.dart | 2 + packages/dart/lib/src/utils.dart | 65 ++ packages/dart/test/hub_test.dart | 55 + .../mocks/mock_metric_capture_pipeline.dart | 17 + .../dart/test/mocks/mock_sentry_client.dart | 13 + .../test/mocks/mock_telemetry_processor.dart | 6 + .../test/protocol/rate_limit_parser_test.dart | 8 + packages/dart/test/sentry_client_test.dart | 29 + .../dart/test/sentry_envelope_item_test.dart | 26 + packages/dart/test/sentry_envelope_test.dart | 31 + packages/dart/test/sentry_options_test.dart | 6 + packages/dart/test/sentry_test.dart | 24 +- .../metric/metric_capture_pipeline_test.dart | 223 ++++ .../test/telemetry/metric/metric_test.dart | 72 ++ .../metrics_setup_integration_test.dart | 95 ++ .../test/telemetry/metric/metrics_test.dart | 151 +++ .../telemetry/processing/processor_test.dart | 43 +- .../platform_integrations_test.dart | 13 +- packages/flutter/example/lib/main.dart | 38 + .../load_contexts_integration.dart | 151 ++- .../integrations/replay_log_integration.dart | 63 -- .../replay_telemetry_integration.dart | 97 ++ packages/flutter/lib/src/sentry_flutter.dart | 6 +- .../load_contexts_integration_test.dart | 971 ++++++++++++++---- .../load_contexts_integrations_test.dart | 468 --------- .../replay_log_integration_test.dart | 303 ------ .../replay_telemetry_integration_test.dart | 220 ++++ packages/flutter/test/mocks.dart | 6 + packages/flutter/test/mocks.mocks.dart | 965 +++++++++-------- .../sentry_screenshot_widget_test.mocks.dart | 1 + 57 files changed, 3442 insertions(+), 1629 deletions(-) create mode 100644 packages/dart/lib/src/telemetry/default_attributes.dart create mode 100644 packages/dart/lib/src/telemetry/metric/default_metrics.dart create mode 100644 packages/dart/lib/src/telemetry/metric/metric.dart create mode 100644 packages/dart/lib/src/telemetry/metric/metric_capture_pipeline.dart create mode 100644 packages/dart/lib/src/telemetry/metric/metrics.dart create mode 100644 packages/dart/lib/src/telemetry/metric/metrics_setup_integration.dart create mode 100644 packages/dart/lib/src/telemetry/metric/noop_metrics.dart create mode 100644 packages/dart/lib/src/telemetry/telemetry.dart create mode 100644 packages/dart/test/mocks/mock_metric_capture_pipeline.dart create mode 100644 packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart create mode 100644 packages/dart/test/telemetry/metric/metric_test.dart create mode 100644 packages/dart/test/telemetry/metric/metrics_setup_integration_test.dart create mode 100644 packages/dart/test/telemetry/metric/metrics_test.dart delete mode 100644 packages/flutter/lib/src/integrations/replay_log_integration.dart create mode 100644 packages/flutter/lib/src/integrations/replay_telemetry_integration.dart delete mode 100644 packages/flutter/test/integrations/load_contexts_integrations_test.dart delete mode 100644 packages/flutter/test/integrations/replay_log_integration_test.dart create mode 100644 packages/flutter/test/integrations/replay_telemetry_integration_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b78bd6643..6b46c7884b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +### Features + +- Trace connected metrics ([#3450](https://github.com/getsentry/sentry-dart/pull/3450)) + - This feature is enabled by default. + - To send metrics use the following APIs: + - `Sentry.metrics.gauge(...)` + - `Sentry.metrics.count(...)` + - `Sentry.metrics.distribution(...)` + ### Dependencies - Bump Android SDK from v8.28.0 to v8.30.0 ([#3451](https://github.com/getsentry/sentry-dart/pull/3451)) diff --git a/packages/dart/lib/sentry.dart b/packages/dart/lib/sentry.dart index 8d01a3181c..c809b5e2af 100644 --- a/packages/dart/lib/sentry.dart +++ b/packages/dart/lib/sentry.dart @@ -61,5 +61,6 @@ export 'src/utils/url_details.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/breadcrumb_log_level.dart'; export 'src/sentry_logger.dart'; +export 'src/telemetry/telemetry.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/internal_logger.dart' show SentryInternalLogger; diff --git a/packages/dart/lib/src/client_reports/discarded_event.dart b/packages/dart/lib/src/client_reports/discarded_event.dart index 24a3471df0..53d8b95bb8 100644 --- a/packages/dart/lib/src/client_reports/discarded_event.dart +++ b/packages/dart/lib/src/client_reports/discarded_event.dart @@ -70,6 +70,8 @@ extension _DataCategoryExtension on DataCategory { return 'feedback'; case DataCategory.metricBucket: return 'metric_bucket'; + case DataCategory.metric: + return 'trace_metric'; } } } diff --git a/packages/dart/lib/src/constants.dart b/packages/dart/lib/src/constants.dart index 640b776832..94759424df 100644 --- a/packages/dart/lib/src/constants.dart +++ b/packages/dart/lib/src/constants.dart @@ -39,3 +39,80 @@ class SentrySpanDescriptions { static String dbOpen({required String dbName}) => 'Open database $dbName'; static String dbClose({required String dbName}) => 'Close database $dbName'; } + +/// Semantic attributes for telemetry. +/// +/// Not all attributes apply to every telemetry type. +/// +/// See https://getsentry.github.io/sentry-conventions/generated/attributes/ +/// for more details. +@internal +abstract class SemanticAttributesConstants { + SemanticAttributesConstants._(); + + /// The source of a span, also referred to as transaction source. + /// + /// Known values are: `'custom'`, `'url'`, `'route'`, `'component'`, `'view'`, `'task'`. + static const sentrySpanSource = 'sentry.span.source'; + + /// Attributes that holds the sample rate that was locally applied to a span. + /// If this attribute is not defined, it means that the span inherited a sampling decision. + /// + /// NOTE: Is only defined on root spans. + static const sentrySampleRate = 'sentry.sample_rate'; + + /// Use this attribute to represent the origin of a span. + static const sentryOrigin = 'sentry.origin'; + + /// The release version of the application + static const sentryRelease = 'sentry.release'; + + /// The environment name (e.g., "production", "staging", "development") + static const sentryEnvironment = 'sentry.environment'; + + /// The segment name (e.g., "GET /users") + static const sentrySegmentName = 'sentry.segment.name'; + + /// The span id of the segment that this span belongs to. + static const sentrySegmentId = 'sentry.segment.id'; + + /// The name of the Sentry SDK (e.g., "sentry.dart.flutter") + static const sentrySdkName = 'sentry.sdk.name'; + + /// The version of the Sentry SDK + static const sentrySdkVersion = 'sentry.sdk.version'; + + /// The replay ID. + static const sentryReplayId = 'sentry.replay_id'; + + /// Whether the replay is buffering (onErrorSampleRate). + static const sentryInternalReplayIsBuffering = + 'sentry._internal.replay_is_buffering'; + + /// The user ID (gated by `sendDefaultPii`). + static const userId = 'user.id'; + + /// The user email (gated by `sendDefaultPii`). + static const userEmail = 'user.email'; + + /// The user IP address (gated by `sendDefaultPii`). + static const userIpAddress = 'user.ip_address'; + + /// The user username (gated by `sendDefaultPii`). + static const userName = 'user.name'; + + /// The operating system name. + static const osName = 'os.name'; + + /// The operating system version. + static const osVersion = 'os.version'; + + /// The device brand (e.g., "Apple", "Samsung"). + static const deviceBrand = 'device.brand'; + + /// The device model identifier (e.g., "iPhone14,2"). + static const deviceModel = 'device.model'; + + /// The device family (e.g., "iOS", "Android"). + static const deviceFamily = 'device.family'; +} diff --git a/packages/dart/lib/src/hub.dart b/packages/dart/lib/src/hub.dart index 5346e2cd69..8ffc57d15b 100644 --- a/packages/dart/lib/src/hub.dart +++ b/packages/dart/lib/src/hub.dart @@ -317,6 +317,38 @@ class Hub { } } + Future captureMetric(SentryMetric metric) async { + if (!_isEnabled) { + _options.log( + SentryLevel.warning, + "Instance is disabled and this 'captureMetric' call is a no-op.", + ); + } else { + final item = _peek(); + late Scope scope; + final s = _cloneAndRunWithScope(item.scope, null); + if (s is Future) { + scope = await s; + } else { + scope = s; + } + + try { + await item.client.captureMetric( + metric, + scope: scope, + ); + } catch (exception, stacktrace) { + _options.log( + SentryLevel.error, + 'Error while capturing metric', + exception: exception, + stackTrace: stacktrace, + ); + } + } + } + FutureOr _cloneAndRunWithScope( Scope scope, ScopeCallback? withScope) async { if (withScope != null) { diff --git a/packages/dart/lib/src/hub_adapter.dart b/packages/dart/lib/src/hub_adapter.dart index 6491f2a951..73ee33c4cf 100644 --- a/packages/dart/lib/src/hub_adapter.dart +++ b/packages/dart/lib/src/hub_adapter.dart @@ -11,6 +11,7 @@ import 'scope.dart'; import 'sentry.dart'; import 'sentry_client.dart'; import 'sentry_options.dart'; +import 'telemetry/metric/metric.dart'; import 'tracing.dart'; /// Hub adapter to make Integrations testable @@ -200,6 +201,10 @@ class HubAdapter implements Hub { @override FutureOr captureLog(SentryLog log) => Sentry.currentHub.captureLog(log); + @override + Future captureMetric(SentryMetric metric) => + Sentry.currentHub.captureMetric(metric); + @override void setAttributes(Map attributes) => Sentry.currentHub.setAttributes(attributes); diff --git a/packages/dart/lib/src/noop_hub.dart b/packages/dart/lib/src/noop_hub.dart index bb486b9e80..81855f0bef 100644 --- a/packages/dart/lib/src/noop_hub.dart +++ b/packages/dart/lib/src/noop_hub.dart @@ -10,6 +10,7 @@ import 'protocol/sentry_feedback.dart'; import 'scope.dart'; import 'sentry_client.dart'; import 'sentry_options.dart'; +import 'telemetry/metric/metric.dart'; import 'tracing.dart'; class NoOpHub implements Hub { @@ -97,6 +98,9 @@ class NoOpHub implements Hub { @override FutureOr captureLog(SentryLog log) async {} + @override + Future captureMetric(SentryMetric metric) async {} + @override ISentrySpan startTransaction( String name, diff --git a/packages/dart/lib/src/noop_sentry_client.dart b/packages/dart/lib/src/noop_sentry_client.dart index 05e526e393..a889df5d20 100644 --- a/packages/dart/lib/src/noop_sentry_client.dart +++ b/packages/dart/lib/src/noop_sentry_client.dart @@ -7,6 +7,7 @@ import 'scope.dart'; import 'sentry_client.dart'; import 'sentry_envelope.dart'; import 'sentry_trace_context_header.dart'; +import 'telemetry/metric/metric.dart'; class NoOpSentryClient implements SentryClient { NoOpSentryClient._(); @@ -69,4 +70,7 @@ class NoOpSentryClient implements SentryClient { @override FutureOr captureLog(SentryLog log, {Scope? scope}) async {} + + @override + Future captureMetric(SentryMetric metric, {Scope? scope}) async {} } diff --git a/packages/dart/lib/src/sdk_lifecycle_hooks.dart b/packages/dart/lib/src/sdk_lifecycle_hooks.dart index fe803e5e27..c0cbcaf343 100644 --- a/packages/dart/lib/src/sdk_lifecycle_hooks.dart +++ b/packages/dart/lib/src/sdk_lifecycle_hooks.dart @@ -96,3 +96,10 @@ class OnSpanFinish extends SdkLifecycleEvent { final ISentrySpan span; } + +@internal +class OnProcessMetric extends SdkLifecycleEvent { + final SentryMetric metric; + + OnProcessMetric(this.metric); +} diff --git a/packages/dart/lib/src/sentry.dart b/packages/dart/lib/src/sentry.dart index 2ea7824950..8e598c9b4b 100644 --- a/packages/dart/lib/src/sentry.dart +++ b/packages/dart/lib/src/sentry.dart @@ -23,6 +23,8 @@ import 'sentry_attachment/sentry_attachment.dart'; import 'sentry_client.dart'; import 'sentry_options.dart'; import 'sentry_run_zoned_guarded.dart'; +import 'telemetry/metric/metrics_setup_integration.dart'; +import 'telemetry/metric/metrics.dart'; import 'telemetry/processing/processor_integration.dart'; import 'tracing.dart'; import 'transport/data_category.dart'; @@ -110,6 +112,7 @@ class Sentry { options.addIntegration(LoadDartDebugImagesIntegration()); } + options.addIntegration(MetricsSetupIntegration()); options.addIntegration(FeatureFlagsIntegration()); options.addIntegration(LogsEnricherIntegration()); options.addIntegration(InMemoryTelemetryProcessorIntegration()); @@ -450,4 +453,6 @@ class Sentry { ); static SentryLogger get logger => currentHub.options.logger; + + static SentryMetrics get metrics => currentHub.options.metrics; } diff --git a/packages/dart/lib/src/sentry_client.dart b/packages/dart/lib/src/sentry_client.dart index 02e6841e1d..bcd4a45419 100644 --- a/packages/dart/lib/src/sentry_client.dart +++ b/packages/dart/lib/src/sentry_client.dart @@ -18,6 +18,8 @@ import 'sentry_exception_factory.dart'; import 'sentry_options.dart'; import 'sentry_stack_trace_factory.dart'; import 'sentry_trace_context_header.dart'; +import 'telemetry/metric/metric.dart'; +import 'telemetry/metric/metric_capture_pipeline.dart'; import 'transport/client_report_transport.dart'; import 'transport/data_category.dart'; import 'transport/http_transport.dart'; @@ -42,6 +44,7 @@ String get defaultIpAddress => _defaultIpAddress; class SentryClient { final SentryOptions _options; final Random? _random; + final MetricCapturePipeline _metricCapturePipeline; static final _emptySentryId = Future.value(SentryId.empty()); @@ -49,7 +52,8 @@ class SentryClient { SentryStackTraceFactory get _stackTraceFactory => _options.stackTraceFactory; /// Instantiates a client using [SentryOptions] - factory SentryClient(SentryOptions options) { + factory SentryClient(SentryOptions options, + {MetricCapturePipeline? metricCapturePipeline}) { if (options.sendClientReports) { options.recorder = ClientReportRecorder(options.clock); } @@ -74,11 +78,12 @@ class SentryClient { if (enableFlutterSpotlight) { options.transport = SpotlightHttpTransport(options, options.transport); } - return SentryClient._(options); + return SentryClient._( + options, metricCapturePipeline ?? MetricCapturePipeline(options)); } /// Instantiates a client using [SentryOptions] - SentryClient._(this._options) + SentryClient._(this._options, this._metricCapturePipeline) : _random = _options.sampleRate == null ? null : Random(); /// Reports an [event] to Sentry.io. @@ -583,6 +588,9 @@ class SentryClient { } } + Future captureMetric(SentryMetric metric, {Scope? scope}) => + _metricCapturePipeline.captureMetric(metric, scope: scope); + FutureOr close() { final flush = _options.telemetryProcessor.flush(); if (flush is Future) { diff --git a/packages/dart/lib/src/sentry_envelope.dart b/packages/dart/lib/src/sentry_envelope.dart index 23cef605a3..7be52b243a 100644 --- a/packages/dart/lib/src/sentry_envelope.dart +++ b/packages/dart/lib/src/sentry_envelope.dart @@ -104,30 +104,29 @@ class SentryEnvelope { factory SentryEnvelope.fromLogsData( List> encodedLogs, SdkVersion sdkVersion, - ) { - // Create the payload in the format expected by Sentry - // Format: {"items": [log1, log2, ...]} - final builder = BytesBuilder(copy: false); - builder.add(utf8.encode('{"items":[')); - for (int i = 0; i < encodedLogs.length; i++) { - if (i > 0) { - builder.add(utf8.encode(',')); - } - builder.add(encodedLogs[i]); - } - builder.add(utf8.encode(']}')); - - return SentryEnvelope( - SentryEnvelopeHeader( - null, - sdkVersion, - ), - [ - SentryEnvelopeItem.fromLogsData( - builder.takeBytes(), encodedLogs.length), - ], - ); - } + ) => + SentryEnvelope( + SentryEnvelopeHeader(null, sdkVersion), + [ + SentryEnvelopeItem.fromLogsData( + _buildItemsPayload(encodedLogs), encodedLogs.length) + ], + ); + + /// Create a [SentryEnvelope] containing raw metric data payload. + /// This is used by the log batcher to send pre-encoded metric batches. + @internal + factory SentryEnvelope.fromMetricsData( + List> encodedMetrics, + SdkVersion sdkVersion, + ) => + SentryEnvelope( + SentryEnvelopeHeader(null, sdkVersion), + [ + SentryEnvelopeItem.fromMetricsData( + _buildItemsPayload(encodedMetrics), encodedMetrics.length) + ], + ); /// Stream binary data representation of `Envelope` file encoded. Stream> envelopeStream(SentryOptions options) async* { @@ -160,6 +159,20 @@ class SentryEnvelope { } } + /// Builds a payload in the format {"items": [item1, item2, ...]} + static Uint8List _buildItemsPayload(List> encodedItems) { + final builder = BytesBuilder(copy: false); + builder.add(utf8.encode('{"items":[')); + for (int i = 0; i < encodedItems.length; i++) { + if (i > 0) { + builder.add(utf8.encode(',')); + } + builder.add(encodedItems[i]); + } + builder.add(utf8.encode(']}')); + return builder.takeBytes(); + } + /// Add an envelope item containing client report data. void addClientReport(ClientReport? clientReport) { if (clientReport != null) { diff --git a/packages/dart/lib/src/sentry_envelope_item.dart b/packages/dart/lib/src/sentry_envelope_item.dart index f626d97882..e633c6cfcc 100644 --- a/packages/dart/lib/src/sentry_envelope_item.dart +++ b/packages/dart/lib/src/sentry_envelope_item.dart @@ -94,6 +94,22 @@ class SentryEnvelopeItem { ); } + /// Create a [SentryEnvelopeItem] which holds pre-encoded metric data. + /// This is used by the buffer to send pre-encoded metric batches. + @internal + factory SentryEnvelopeItem.fromMetricsData( + List payload, int metricsCount) { + return SentryEnvelopeItem( + SentryEnvelopeItemHeader( + SentryItemType.metric, + itemCount: metricsCount, + contentType: 'application/vnd.sentry.items.trace-metric+json', + ), + () => payload, + originalObject: null, + ); + } + /// Header with info about type and length of data in bytes. final SentryEnvelopeItemHeader header; diff --git a/packages/dart/lib/src/sentry_item_type.dart b/packages/dart/lib/src/sentry_item_type.dart index c712ad8793..3d0fe8d956 100644 --- a/packages/dart/lib/src/sentry_item_type.dart +++ b/packages/dart/lib/src/sentry_item_type.dart @@ -6,5 +6,6 @@ class SentryItemType { static const String profile = 'profile'; static const String statsd = 'statsd'; static const String log = 'log'; + static const String metric = 'trace_metric'; static const String unknown = '__unknown__'; } diff --git a/packages/dart/lib/src/sentry_logger.dart b/packages/dart/lib/src/sentry_logger.dart index 1d324e0678..a643ac8eec 100644 --- a/packages/dart/lib/src/sentry_logger.dart +++ b/packages/dart/lib/src/sentry_logger.dart @@ -6,6 +6,7 @@ import 'protocol/sentry_log_level.dart'; import 'protocol/sentry_attribute.dart'; import 'sentry_options.dart'; import 'sentry_logger_formatter.dart'; +import 'utils.dart'; class SentryLogger { SentryLogger(this._clock, {Hub? hub}) : _hub = hub ?? HubAdapter(); @@ -89,47 +90,6 @@ class SentryLogger { if (attributes == null || attributes.isEmpty) { return body; } - - final attrsStr = attributes.entries - .map((e) => '"${e.key}": ${_formatAttributeValue(e.value)}') - .join(', '); - - return '$body {$attrsStr}'; - } - - /// Format attribute value based on its type - String _formatAttributeValue(SentryAttribute attribute) { - switch (attribute.type) { - case 'string': - if (attribute.value is String) { - return '"${attribute.value}"'; - } - break; - case 'boolean': - if (attribute.value is bool) { - return attribute.value.toString(); - } - break; - case 'integer': - if (attribute.value is int) { - return attribute.value.toString(); - } - break; - case 'double': - if (attribute.value is double) { - final value = attribute.value as double; - // Handle special double values - if (value.isNaN || value.isInfinite) { - return value.toString(); - } - // Ensure doubles always show decimal notation to distinguish from ints - // Use toStringAsFixed(1) for whole numbers, toString() for decimals - return value == value.toInt() - ? value.toStringAsFixed(1) - : value.toString(); - } - break; - } - return attribute.value.toString(); + return '$body ${attributes.toFormattedString()}'; } } diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index f0b7472f3e..d36e29d2c9 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -12,6 +12,7 @@ import 'noop_client.dart'; import 'platform/platform.dart'; import 'sentry_exception_factory.dart'; import 'sentry_stack_trace_factory.dart'; +import 'telemetry/metric/noop_metrics.dart'; import 'telemetry/processing/processor.dart'; import 'transport/noop_transport.dart'; import 'version.dart'; @@ -217,6 +218,10 @@ class SentryOptions { /// Can return a modified log or null to drop the log. BeforeSendLogCallback? beforeSendLog; + /// This function is called right before a metric is about to be sent. + /// Can return a modified metric or null to drop the metric. + BeforeSendMetricCallback? beforeSendMetric; + /// Sets the release. SDK will try to automatically configure a release out of the box /// See [docs for further information](https://docs.sentry.io/platforms/flutter/configuration/releases/) String? release; @@ -545,6 +550,11 @@ class SentryOptions { /// Disabled by default. bool enableLogs = false; + /// Enable to capture and send metrics to Sentry. + /// + /// Enabled by default. + bool enableMetrics = true; + /// Enables adding the module in [SentryStackFrame.module]. /// This option only has an effect in non-obfuscated builds. /// Enabling this option may change grouping. @@ -552,6 +562,9 @@ class SentryOptions { late final SentryLogger logger = SentryLogger(clock); + @internal + late SentryMetrics metrics = const NoOpSentryMetrics(); + @internal TelemetryProcessor telemetryProcessor = NoOpTelemetryProcessor(); @@ -688,6 +701,11 @@ typedef BeforeMetricCallback = bool Function( /// Can return a modified log or null to drop the log. typedef BeforeSendLogCallback = FutureOr Function(SentryLog log); +/// This function is called right before a metric is about to be emitted. +/// Can return true to emit the metric, or false to drop it. +typedef BeforeSendMetricCallback = FutureOr Function( + SentryMetric metric); + /// Used to provide timestamp for logging. typedef ClockProvider = DateTime Function(); diff --git a/packages/dart/lib/src/telemetry/default_attributes.dart b/packages/dart/lib/src/telemetry/default_attributes.dart new file mode 100644 index 0000000000..93facb066a --- /dev/null +++ b/packages/dart/lib/src/telemetry/default_attributes.dart @@ -0,0 +1,55 @@ +import '../../sentry.dart'; +import '../utils/os_utils.dart'; + +final _operatingSystem = getSentryOperatingSystem(); + +Map defaultAttributes(SentryOptions options, + {Scope? scope}) { + final attributes = {}; + + attributes[SemanticAttributesConstants.sentrySdkName] = + SentryAttribute.string(options.sdk.name); + + attributes[SemanticAttributesConstants.sentrySdkVersion] = + SentryAttribute.string(options.sdk.version); + + if (options.environment != null) { + attributes[SemanticAttributesConstants.sentryEnvironment] = + SentryAttribute.string(options.environment!); + } + + if (options.release != null) { + attributes[SemanticAttributesConstants.sentryRelease] = + SentryAttribute.string(options.release!); + } + + if (options.sendDefaultPii) { + final user = scope?.user; + if (user != null) { + if (user.id != null) { + attributes[SemanticAttributesConstants.userId] = + SentryAttribute.string(user.id!); + } + if (user.name != null) { + attributes[SemanticAttributesConstants.userName] = + SentryAttribute.string(user.name!); + } + if (user.email != null) { + attributes[SemanticAttributesConstants.userEmail] = + SentryAttribute.string(user.email!); + } + } + } + + if (_operatingSystem.name != null) { + attributes[SemanticAttributesConstants.osName] = + SentryAttribute.string(_operatingSystem.name!); + } + + if (_operatingSystem.version != null) { + attributes[SemanticAttributesConstants.osVersion] = + SentryAttribute.string(_operatingSystem.version!); + } + + return attributes; +} diff --git a/packages/dart/lib/src/telemetry/metric/default_metrics.dart b/packages/dart/lib/src/telemetry/metric/default_metrics.dart new file mode 100644 index 0000000000..b2aeda5f3e --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/default_metrics.dart @@ -0,0 +1,92 @@ +import 'dart:async'; + +import '../../../sentry.dart'; +import '../../utils/internal_logger.dart'; + +typedef CaptureMetricCallback = Future Function(SentryMetric metric); +typedef ScopeProvider = Scope Function(); + +final class DefaultSentryMetrics implements SentryMetrics { + final CaptureMetricCallback _captureMetricCallback; + final ClockProvider _clockProvider; + final ScopeProvider _scopeProvider; + + DefaultSentryMetrics( + {required CaptureMetricCallback captureMetricCallback, + required ClockProvider clockProvider, + required ScopeProvider scopeProvider}) + : _captureMetricCallback = captureMetricCallback, + _clockProvider = clockProvider, + _scopeProvider = scopeProvider; + + @override + void count( + String name, + int value, { + Map? attributes, + }) { + internalLogger.debug(() => + 'Sentry.metrics.count("$name", $value) called with attributes ${_formatAttributes(attributes)}'); + + final metric = SentryCounterMetric( + timestamp: _clockProvider(), + name: name, + value: value, + spanId: _scopeProvider().span?.context.spanId, + traceId: _scopeProvider().propagationContext.traceId, + attributes: attributes ?? {}); + + unawaited(_captureMetricCallback(metric)); + } + + @override + void gauge( + String name, + num value, { + String? unit, + Map? attributes, + }) { + internalLogger.debug(() => + 'Sentry.metrics.gauge("$name", $value${_formatUnit(unit)}) called with attributes ${_formatAttributes(attributes)}'); + + final metric = SentryGaugeMetric( + timestamp: _clockProvider(), + name: name, + value: value, + unit: unit, + spanId: _scopeProvider().span?.context.spanId, + traceId: _scopeProvider().propagationContext.traceId, + attributes: attributes ?? {}); + + unawaited(_captureMetricCallback(metric)); + } + + @override + void distribution( + String name, + num value, { + String? unit, + Map? attributes, + }) { + internalLogger.debug(() => + 'Sentry.metrics.distribution("$name", $value${_formatUnit(unit)}) called with attributes ${_formatAttributes(attributes)}'); + + final metric = SentryDistributionMetric( + timestamp: _clockProvider(), + name: name, + value: value, + unit: unit, + spanId: _scopeProvider().span?.context.spanId, + traceId: _scopeProvider().propagationContext.traceId, + attributes: attributes ?? {}); + + unawaited(_captureMetricCallback(metric)); + } + + String _formatUnit(String? unit) => unit != null ? ', unit: $unit' : ''; + + String _formatAttributes(Map? attributes) { + final formatted = attributes?.toFormattedString() ?? ''; + return formatted.isEmpty ? '' : ' $formatted'; + } +} diff --git a/packages/dart/lib/src/telemetry/metric/metric.dart b/packages/dart/lib/src/telemetry/metric/metric.dart new file mode 100644 index 0000000000..35cf843f50 --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/metric.dart @@ -0,0 +1,182 @@ +import 'package:meta/meta.dart'; + +import '../../../sentry.dart'; + +/// Base class for metric data points sent to Sentry. +/// +/// See [SentryCounterMetric], [SentryGaugeMetric], and [SentryDistributionMetric] +/// for concrete metric types. +abstract class SentryMetric { + /// The metric type identifier (e.g., 'counter', 'gauge', 'distribution'). + final String type; + + /// The time when the metric was recorded. + DateTime timestamp; + + /// The metric name, typically using dot notation (e.g., 'app.memory_usage'). + String name; + + /// The numeric value of the metric. + num value; + + /// The trace ID from the current propagation context. + SentryId traceId; + + /// The span ID of the active span when the metric was recorded. + SpanId? spanId; + + /// The unit of measurement (e.g., 'millisecond', 'byte'). + /// + /// See [SentryMetricUnit] for predefined unit constants. + String? unit; + + /// Custom key-value pairs attached to the metric. + Map attributes; + + SentryMetric({ + required this.timestamp, + required this.type, + required this.name, + required this.value, + required this.traceId, + this.spanId, + this.unit, + Map? attributes, + }) : attributes = attributes ?? {}; + + @internal + Map toJson() { + return { + 'timestamp': timestamp.millisecondsSinceEpoch / 1000.0, + 'type': type, + 'name': name, + 'value': value, + 'trace_id': traceId.toString(), + if (spanId != null) 'span_id': spanId.toString(), + if (unit != null) 'unit': unit, + if (attributes.isNotEmpty) + 'attributes': attributes.map((k, v) => MapEntry(k, v.toJson())), + }; + } +} + +/// A metric that tracks the number of times an event occurs. +final class SentryCounterMetric extends SentryMetric { + SentryCounterMetric({ + required super.timestamp, + required super.name, + required super.value, + required super.traceId, + super.spanId, + super.unit, + super.attributes, + }) : super(type: 'counter'); +} + +/// A metric that tracks a value which can increase or decrease over time. +/// +/// See [SentryMetricUnit] for predefined unit constants. +final class SentryGaugeMetric extends SentryMetric { + SentryGaugeMetric({ + required super.timestamp, + required super.name, + required super.value, + required super.traceId, + super.spanId, + super.unit, + super.attributes, + }) : super(type: 'gauge'); +} + +/// A metric that tracks the statistical distribution of a set of values. +/// +/// See [SentryMetricUnit] for predefined unit constants. +final class SentryDistributionMetric extends SentryMetric { + SentryDistributionMetric({ + required super.timestamp, + required super.name, + required super.value, + required super.traceId, + super.spanId, + super.unit, + super.attributes, + }) : super(type: 'distribution'); +} + +/// String constants for metric units. +/// +/// These constants represent the API names of measurement units that can be +/// used with metrics. +abstract final class SentryMetricUnit { + /// Nanosecond, 10^-9 seconds. + static const String nanosecond = 'nanosecond'; + + /// Microsecond, 10^-6 seconds. + static const String microsecond = 'microsecond'; + + /// Millisecond, 10^-3 seconds. + static const String millisecond = 'millisecond'; + + /// Full second. + static const String second = 'second'; + + /// Minute, 60 seconds. + static const String minute = 'minute'; + + /// Hour, 3600 seconds. + static const String hour = 'hour'; + + /// Day, 86,400 seconds. + static const String day = 'day'; + + /// Week, 604,800 seconds. + static const String week = 'week'; + + /// Bit, corresponding to 1/8 of a byte. + static const String bit = 'bit'; + + /// Byte. + static const String byte = 'byte'; + + /// Kilobyte, 10^3 bytes. + static const String kilobyte = 'kilobyte'; + + /// Kibibyte, 2^10 bytes. + static const String kibibyte = 'kibibyte'; + + /// Megabyte, 10^6 bytes. + static const String megabyte = 'megabyte'; + + /// Mebibyte, 2^20 bytes. + static const String mebibyte = 'mebibyte'; + + /// Gigabyte, 10^9 bytes. + static const String gigabyte = 'gigabyte'; + + /// Gibibyte, 2^30 bytes. + static const String gibibyte = 'gibibyte'; + + /// Terabyte, 10^12 bytes. + static const String terabyte = 'terabyte'; + + /// Tebibyte, 2^40 bytes. + static const String tebibyte = 'tebibyte'; + + /// Petabyte, 10^15 bytes. + static const String petabyte = 'petabyte'; + + /// Pebibyte, 2^50 bytes. + static const String pebibyte = 'pebibyte'; + + /// Exabyte, 10^18 bytes. + static const String exabyte = 'exabyte'; + + /// Exbibyte, 2^60 bytes. + static const String exbibyte = 'exbibyte'; + + /// Floating point fraction of `1`. + static const String ratio = 'ratio'; + + /// Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. + static const String percent = 'percent'; +} diff --git a/packages/dart/lib/src/telemetry/metric/metric_capture_pipeline.dart b/packages/dart/lib/src/telemetry/metric/metric_capture_pipeline.dart new file mode 100644 index 0000000000..9bfa7fc23e --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/metric_capture_pipeline.dart @@ -0,0 +1,72 @@ +import 'package:meta/meta.dart'; + +import '../../../sentry.dart'; +import '../../client_reports/discard_reason.dart'; +import '../../transport/data_category.dart'; +import '../../utils/internal_logger.dart'; +import '../default_attributes.dart'; + +@internal +class MetricCapturePipeline { + final SentryOptions _options; + + MetricCapturePipeline(this._options); + + Future captureMetric(SentryMetric metric, {Scope? scope}) async { + if (!_options.enableMetrics) { + internalLogger.debug( + '$MetricCapturePipeline: Metrics disabled, dropping ${metric.name}'); + return; + } + + try { + if (scope != null) { + metric.attributes.addAllIfAbsent(scope.attributes); + } + + await _options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + metric.attributes + .addAllIfAbsent(defaultAttributes(_options, scope: scope)); + + final beforeSendMetric = _options.beforeSendMetric; + SentryMetric? processedMetric = metric; + if (beforeSendMetric != null) { + try { + processedMetric = await beforeSendMetric(metric); + } catch (exception, stackTrace) { + _options.log( + SentryLevel.error, + 'The beforeSendMetric callback threw an exception', + exception: exception, + stackTrace: stackTrace, + ); + if (_options.automatedTestMode) { + rethrow; + } + } + } + if (processedMetric == null) { + _options.recorder + .recordLostEvent(DiscardReason.beforeSend, DataCategory.metric); + internalLogger.debug( + '$MetricCapturePipeline: Metric ${metric.name} dropped by beforeSendMetric'); + return; + } + + _options.telemetryProcessor.addMetric(processedMetric); + internalLogger.debug( + '$MetricCapturePipeline: Metric ${processedMetric.name} (${processedMetric.type}) captured'); + } catch (exception, stackTrace) { + internalLogger.error( + 'Error capturing metric ${metric.name}', + error: exception, + stackTrace: stackTrace, + ); + if (_options.automatedTestMode) { + rethrow; + } + } + } +} diff --git a/packages/dart/lib/src/telemetry/metric/metrics.dart b/packages/dart/lib/src/telemetry/metric/metrics.dart new file mode 100644 index 0000000000..81a689cec9 --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/metrics.dart @@ -0,0 +1,80 @@ +import '../../../sentry.dart'; + +/// Interface for emitting custom metrics to Sentry. +/// +/// Access via [Sentry.metrics]. +abstract interface class SentryMetrics { + /// Increments a cumulative counter by [value]. + /// + /// Use counters for values that only increase, like request counts or error + /// totals. The [name] identifies the metric (e.g., `'api.requests'`). + /// Optionally attach [attributes] to add dimensions for filtering. + /// + /// ```dart + /// Sentry.metrics.count( + /// 'api.requests', + /// 1, + /// attributes: { + /// 'endpoint': SentryAttribute.string('/api/users'), + /// 'method': SentryAttribute.string('POST'), + /// }, + /// ); + /// ``` + void count( + String name, + int value, { + Map? attributes, + }); + + /// Records a point-in-time [value] that can increase or decrease. + /// + /// Use gauges for values that fluctuate, like memory usage, queue depth, or + /// active connections. The [name] identifies the metric. Specify [unit] to + /// describe the measurement— [SentryMetricUnit] provides officially supported + /// units (e.g., [SentryMetricUnit.byte]), but custom strings are also + /// accepted. Optionally attach [attributes] to add dimensions for filtering. + /// + /// ```dart + /// Sentry.metrics.gauge( + /// 'memory.heap_used', + /// 1, + /// unit: SentryMetricUnit.megabyte, + /// attributes: { + /// 'process': SentryAttribute.string('main'), + /// }, + /// ); + /// ``` + void gauge( + String name, + num value, { + String? unit, + Map? attributes, + }); + + /// Records a [value] for statistical distribution analysis. + /// + /// Use distributions to track values where you need percentiles, averages, + /// and histograms—like response times or payload sizes. The [name] identifies + /// the metric. Specify [unit] to describe the measurement — [SentryMetricUnit] + /// provides officially supported units (e.g., [SentryMetricUnit.millisecond]), + /// but custom strings are also accepted. Optionally attach [attributes] to + /// add dimensions for filtering. + /// + /// ```dart + /// Sentry.metrics.distribution( + /// 'http.request.duration', + /// 245.3, + /// unit: SentryMetricUnit.millisecond, + /// attributes: { + /// 'endpoint': SentryAttribute.string('/api/users'), + /// 'status_code': SentryAttribute.int(200), + /// }, + /// ); + /// ``` + void distribution( + String name, + num value, { + String? unit, + Map? attributes, + }); +} diff --git a/packages/dart/lib/src/telemetry/metric/metrics_setup_integration.dart b/packages/dart/lib/src/telemetry/metric/metrics_setup_integration.dart new file mode 100644 index 0000000000..2052904db1 --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/metrics_setup_integration.dart @@ -0,0 +1,32 @@ +import '../../../sentry.dart'; +import '../../utils/internal_logger.dart'; +import 'default_metrics.dart'; +import 'noop_metrics.dart'; + +/// Integration that sets up the default Sentry metrics implementation. +class MetricsSetupIntegration extends Integration { + static const integrationName = 'MetricsSetup'; + + @override + void call(Hub hub, SentryOptions options) { + if (!options.enableMetrics) { + internalLogger + .debug('$integrationName: Metrics disabled, skipping setup'); + return; + } + + if (options.metrics is! NoOpSentryMetrics) { + internalLogger.debug( + '$integrationName: Custom metrics already configured, skipping setup'); + return; + } + + options.metrics = DefaultSentryMetrics( + captureMetricCallback: hub.captureMetric, + clockProvider: options.clock, + scopeProvider: () => hub.scope); + + options.sdk.addIntegration(integrationName); + internalLogger.debug('$integrationName: Metrics configured successfully'); + } +} diff --git a/packages/dart/lib/src/telemetry/metric/noop_metrics.dart b/packages/dart/lib/src/telemetry/metric/noop_metrics.dart new file mode 100644 index 0000000000..aa53620b42 --- /dev/null +++ b/packages/dart/lib/src/telemetry/metric/noop_metrics.dart @@ -0,0 +1,28 @@ +import '../../../sentry.dart'; + +final class NoOpSentryMetrics implements SentryMetrics { + const NoOpSentryMetrics(); + + @override + void count( + String name, + int value, { + Map? attributes, + }) {} + + @override + void distribution( + String name, + num value, { + String? unit, + Map? attributes, + }) {} + + @override + void gauge( + String name, + num value, { + String? unit, + Map? attributes, + }) {} +} diff --git a/packages/dart/lib/src/telemetry/processing/processor.dart b/packages/dart/lib/src/telemetry/processing/processor.dart index 670835524e..778d7accb7 100644 --- a/packages/dart/lib/src/telemetry/processing/processor.dart +++ b/packages/dart/lib/src/telemetry/processing/processor.dart @@ -14,6 +14,9 @@ abstract class TelemetryProcessor { /// Adds a log to be processed and buffered. void addLog(SentryLog log); + /// Adds a metric to be processed and buffered. + void addMetric(SentryMetric metric); + /// Flushes all buffered telemetry data. /// /// Returns a [Future] if any buffer performs async flushing, otherwise @@ -27,6 +30,12 @@ abstract class TelemetryProcessor { /// instances. If no buffer is registered for a telemetry type, items are /// dropped with a warning. class DefaultTelemetryProcessor implements TelemetryProcessor { + /// The buffer for metric data, or `null` if metric buffering is disabled. + final TelemetryBuffer? _metricBuffer; + + @visibleForTesting + TelemetryBuffer? get metricBuffer => _metricBuffer; + /// The buffer for log data, or `null` if log buffering is disabled. final TelemetryBuffer? _logBuffer; @@ -34,32 +43,47 @@ class DefaultTelemetryProcessor implements TelemetryProcessor { TelemetryBuffer? get logBuffer => _logBuffer; DefaultTelemetryProcessor({ + TelemetryBuffer? metricBuffer, TelemetryBuffer? logBuffer, - }) : _logBuffer = logBuffer; + }) : _metricBuffer = metricBuffer, + _logBuffer = logBuffer; @override void addLog(SentryLog log) { - if (logBuffer == null) { + if (_logBuffer == null) { internalLogger.warning( '$runtimeType: No buffer registered for ${log.runtimeType} - item was dropped', ); return; } - logBuffer!.add(log); + _logBuffer.add(log); + } + + @override + void addMetric(SentryMetric metric) { + if (_metricBuffer == null) { + internalLogger.warning( + '$runtimeType: No buffer registered for ${metric.runtimeType} - item was dropped', + ); + return; + } + + _metricBuffer.add(metric); } @override FutureOr flush() { internalLogger.debug('$runtimeType: Clearing buffers'); - final result = logBuffer?.flush(); + final results = [_logBuffer?.flush(), _metricBuffer?.flush()]; - if (result is Future) { - return result; + final futures = results.whereType().toList(); + if (futures.isEmpty) { + return null; } - return null; + return Future.wait(futures).then((_) {}); } } @@ -67,6 +91,9 @@ class NoOpTelemetryProcessor implements TelemetryProcessor { @override void addLog(SentryLog log) {} + @override + void addMetric(SentryMetric log) {} + @override FutureOr flush() {} } diff --git a/packages/dart/lib/src/telemetry/processing/processor_integration.dart b/packages/dart/lib/src/telemetry/processing/processor_integration.dart index cc4fc2ad24..bbf8be767f 100644 --- a/packages/dart/lib/src/telemetry/processing/processor_integration.dart +++ b/packages/dart/lib/src/telemetry/processing/processor_integration.dart @@ -20,8 +20,9 @@ class InMemoryTelemetryProcessorIntegration extends Integration { return; } - options.telemetryProcessor = - DefaultTelemetryProcessor(logBuffer: _createLogBuffer(options)); + options.telemetryProcessor = DefaultTelemetryProcessor( + logBuffer: _createLogBuffer(options), + metricBuffer: _createMetricBuffer(options)); options.sdk.addIntegration(integrationName); } @@ -34,4 +35,15 @@ class InMemoryTelemetryProcessorIntegration extends Integration { items.map((item) => item).toList(), options.sdk); return options.transport.send(envelope).then((_) {}); }); + + InMemoryTelemetryBuffer _createMetricBuffer( + SentryOptions options) => + InMemoryTelemetryBuffer( + encoder: (SentryMetric item) => + utf8JsonEncoder.convert(item.toJson()), + onFlush: (items) { + final envelope = SentryEnvelope.fromMetricsData( + items.map((item) => item).toList(), options.sdk); + return options.transport.send(envelope).then((_) {}); + }); } diff --git a/packages/dart/lib/src/telemetry/telemetry.dart b/packages/dart/lib/src/telemetry/telemetry.dart new file mode 100644 index 0000000000..f1bbe2e574 --- /dev/null +++ b/packages/dart/lib/src/telemetry/telemetry.dart @@ -0,0 +1,2 @@ +export 'metric/metrics.dart'; +export 'metric/metric.dart'; diff --git a/packages/dart/lib/src/transport/data_category.dart b/packages/dart/lib/src/transport/data_category.dart index 89f983f3a7..5dbba0f392 100644 --- a/packages/dart/lib/src/transport/data_category.dart +++ b/packages/dart/lib/src/transport/data_category.dart @@ -11,6 +11,7 @@ enum DataCategory { metricBucket, logItem, feedback, + metric, unknown; static DataCategory fromItemType(String itemType) { @@ -29,6 +30,8 @@ enum DataCategory { return DataCategory.metricBucket; case 'log': return DataCategory.logItem; + case 'trace_metric': + return DataCategory.metric; case 'feedback': return DataCategory.feedback; default: diff --git a/packages/dart/lib/src/transport/rate_limit_parser.dart b/packages/dart/lib/src/transport/rate_limit_parser.dart index f0fea1dfde..642f53815a 100644 --- a/packages/dart/lib/src/transport/rate_limit_parser.dart +++ b/packages/dart/lib/src/transport/rate_limit_parser.dart @@ -89,6 +89,8 @@ extension _DataCategoryExtension on DataCategory { return DataCategory.metricBucket; case 'log_item': return DataCategory.logItem; + case 'trace_metric': + return DataCategory.metric; } return DataCategory.unknown; } diff --git a/packages/dart/lib/src/utils.dart b/packages/dart/lib/src/utils.dart index db5ca614c2..407bceab07 100644 --- a/packages/dart/lib/src/utils.dart +++ b/packages/dart/lib/src/utils.dart @@ -6,6 +6,8 @@ import 'dart:convert'; import 'package:meta/meta.dart'; +import 'protocol/sentry_attribute.dart'; + /// Sentry does not take a timezone and instead expects the date-time to be /// submitted in UTC timezone. @internal @@ -34,3 +36,66 @@ Object? jsonSerializationFallback(Object? nonEncodable) { } return nonEncodable.toString(); } + +@internal +extension AddAllAbsentX on Map { + void addAllIfAbsent(Map other) { + for (final e in other.entries) { + putIfAbsent(e.key, () => e.value); + } + } +} + +@internal +extension SentryAttributeFormatting on SentryAttribute { + /// Formats the attribute value for debug/log output. + /// + /// Strings are quoted, numbers and booleans are shown as-is. + String toFormattedString() { + switch (type) { + case 'string': + if (value is String) { + return '"$value"'; + } + break; + case 'boolean': + if (value is bool) { + return value.toString(); + } + break; + case 'integer': + if (value is int) { + return value.toString(); + } + break; + case 'double': + if (value is double) { + final doubleValue = value as double; + // Handle special double values + if (doubleValue.isNaN || doubleValue.isInfinite) { + return doubleValue.toString(); + } + // Ensure doubles always show decimal notation to distinguish from ints + return doubleValue == doubleValue.toInt() + ? doubleValue.toStringAsFixed(1) + : doubleValue.toString(); + } + break; + } + return value.toString(); + } +} + +@internal +extension SentryAttributeMapFormatting on Map { + /// Formats attributes as `{key1: value1, key2: value2}`. + /// + /// Returns an empty string if the map is empty. + String toFormattedString() { + if (isEmpty) return ''; + final attrsStr = entries + .map((e) => '"${e.key}": ${e.value.toFormattedString()}') + .join(', '); + return '{$attrsStr}'; + } +} diff --git a/packages/dart/test/hub_test.dart b/packages/dart/test/hub_test.dart index ab9f11e048..a5dcc6e1c5 100644 --- a/packages/dart/test/hub_test.dart +++ b/packages/dart/test/hub_test.dart @@ -943,6 +943,61 @@ void main() { expect(fixture.client.captureLogCalls.first.log, log); }); }); + + group('Hub Metrics', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + SentryMetric givenMetric() { + return SentryCounterMetric( + timestamp: DateTime.now().toUtc(), + name: 'test-metric', + value: 1, + traceId: SentryId.newId(), + attributes: { + 'attribute': SentryAttribute.string('value'), + }, + ); + } + + test('captures metrics', () async { + final hub = fixture.getSut(); + + final metric = givenMetric(); + await hub.captureMetric(metric); + + expect(fixture.client.captureMetricCalls.length, 1); + expect(fixture.client.captureMetricCalls.first.metric, metric); + }); + + test('does not capture metric when hub is disabled', () async { + final hub = fixture.getSut(); + await hub.close(); + + final metric = givenMetric(); + await hub.captureMetric(metric); + + expect(fixture.client.captureMetricCalls, isEmpty); + }); + + test('passes scope to client', () async { + final hub = fixture.getSut(); + hub.configureScope((scope) { + scope.setTag('test-tag', 'test-value'); + }); + + final metric = givenMetric(); + await hub.captureMetric(metric); + + expect(fixture.client.captureMetricCalls.length, 1); + final capturedScope = fixture.client.captureMetricCalls.first.scope; + expect(capturedScope, isNotNull); + expect(capturedScope!.tags['test-tag'], 'test-value'); + }); + }); } class Fixture { diff --git a/packages/dart/test/mocks/mock_metric_capture_pipeline.dart b/packages/dart/test/mocks/mock_metric_capture_pipeline.dart new file mode 100644 index 0000000000..d714b512f6 --- /dev/null +++ b/packages/dart/test/mocks/mock_metric_capture_pipeline.dart @@ -0,0 +1,17 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/metric/metric_capture_pipeline.dart'; + +import 'mock_sentry_client.dart'; + +class MockMetricCapturePipeline extends MetricCapturePipeline { + MockMetricCapturePipeline(super.options); + + final List captureMetricCalls = []; + + int get callCount => captureMetricCalls.length; + + @override + Future captureMetric(SentryMetric metric, {Scope? scope}) async { + captureMetricCalls.add(CaptureMetricCall(metric, scope)); + } +} diff --git a/packages/dart/test/mocks/mock_sentry_client.dart b/packages/dart/test/mocks/mock_sentry_client.dart index 00a61cc203..e6550a6ba7 100644 --- a/packages/dart/test/mocks/mock_sentry_client.dart +++ b/packages/dart/test/mocks/mock_sentry_client.dart @@ -11,6 +11,7 @@ class MockSentryClient with NoSuchMethodProvider implements SentryClient { List captureTransactionCalls = []; List captureFeedbackCalls = []; List captureLogCalls = []; + List captureMetricCalls = []; int closeCalls = 0; @override @@ -90,6 +91,11 @@ class MockSentryClient with NoSuchMethodProvider implements SentryClient { captureLogCalls.add(CaptureLogCall(log, scope)); } + @override + Future captureMetric(SentryMetric metric, {Scope? scope}) async { + captureMetricCalls.add(CaptureMetricCall(metric, scope)); + } + @override void close() { closeCalls = closeCalls + 1; @@ -186,3 +192,10 @@ class CaptureLogCall { CaptureLogCall(this.log, this.scope); } + +class CaptureMetricCall { + final SentryMetric metric; + final Scope? scope; + + CaptureMetricCall(this.metric, this.scope); +} diff --git a/packages/dart/test/mocks/mock_telemetry_processor.dart b/packages/dart/test/mocks/mock_telemetry_processor.dart index a52fd97a2f..34dd0ba744 100644 --- a/packages/dart/test/mocks/mock_telemetry_processor.dart +++ b/packages/dart/test/mocks/mock_telemetry_processor.dart @@ -3,6 +3,7 @@ import 'package:sentry/src/telemetry/processing/processor.dart'; class MockTelemetryProcessor implements TelemetryProcessor { final List addedLogs = []; + final List addedMetrics = []; int flushCalls = 0; int closeCalls = 0; @@ -11,6 +12,11 @@ class MockTelemetryProcessor implements TelemetryProcessor { addedLogs.add(log); } + @override + void addMetric(SentryMetric metric) { + addedMetrics.add(metric); + } + @override void flush() { flushCalls++; diff --git a/packages/dart/test/protocol/rate_limit_parser_test.dart b/packages/dart/test/protocol/rate_limit_parser_test.dart index 567dec34f0..cf62c03d5c 100644 --- a/packages/dart/test/protocol/rate_limit_parser_test.dart +++ b/packages/dart/test/protocol/rate_limit_parser_test.dart @@ -114,6 +114,14 @@ void main() { expect(sut[0].category, DataCategory.metricBucket); expect(sut[0].namespaces, isEmpty); }); + + test('parse trace_metric category', () { + final sut = RateLimitParser('60:trace_metric').parseRateLimitHeader(); + + expect(sut.length, 1); + expect(sut[0].category, DataCategory.metric); + expect(sut[0].duration.inMilliseconds, 60000); + }); }); group('parseRetryAfterHeader', () { diff --git a/packages/dart/test/sentry_client_test.dart b/packages/dart/test/sentry_client_test.dart index e7c46ab55e..c2c7eb1e6f 100644 --- a/packages/dart/test/sentry_client_test.dart +++ b/packages/dart/test/sentry_client_test.dart @@ -23,6 +23,7 @@ import 'package:http/http.dart' as http; import 'mocks.dart'; import 'mocks/mock_client_report_recorder.dart'; import 'mocks/mock_hub.dart'; +import 'mocks/mock_metric_capture_pipeline.dart'; import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'test_utils.dart'; @@ -2060,6 +2061,34 @@ void main() { }); }); + group('SentryClient captureMetric', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + test('delegates to metric pipeline', () async { + final pipeline = MockMetricCapturePipeline(fixture.options); + final client = + SentryClient(fixture.options, metricCapturePipeline: pipeline); + final scope = Scope(fixture.options); + + final metric = SentryCounterMetric( + timestamp: DateTime.now().toUtc(), + name: 'test-metric', + value: 1, + traceId: SentryId.newId(), + ); + + await client.captureMetric(metric, scope: scope); + + expect(pipeline.callCount, 1); + expect(pipeline.captureMetricCalls.first.metric, same(metric)); + expect(pipeline.captureMetricCalls.first.scope, same(scope)); + }); + }); + group('SentryClient captures envelope', () { late Fixture fixture; final fakeEnvelope = getFakeEnvelope(); diff --git a/packages/dart/test/sentry_envelope_item_test.dart b/packages/dart/test/sentry_envelope_item_test.dart index 54f534de61..cca111b6a0 100644 --- a/packages/dart/test/sentry_envelope_item_test.dart +++ b/packages/dart/test/sentry_envelope_item_test.dart @@ -157,5 +157,31 @@ void main() { expect(sut.originalObject, null); }); + + test('fromMetricsData creates item with correct headers and payload', + () async { + final payload = + utf8.encode('{"items":[{"test":"metric1"},{"test":"metric2"}]}'); + final metricsCount = 2; + + final sut = SentryEnvelopeItem.fromMetricsData(payload, metricsCount); + + expect(sut.header.contentType, + 'application/vnd.sentry.items.trace-metric+json'); + expect(sut.header.type, SentryItemType.metric); + expect(sut.header.itemCount, metricsCount); + + final actualData = await sut.dataFactory(); + expect(actualData, payload); + }); + + test('fromMetricsData does not set originalObject', () async { + final payload = utf8.encode('{"items":[{"test":"metric"}]}'); + final metricsCount = 1; + + final sut = SentryEnvelopeItem.fromMetricsData(payload, metricsCount); + + expect(sut.originalObject, null); + }); }); } diff --git a/packages/dart/test/sentry_envelope_test.dart b/packages/dart/test/sentry_envelope_test.dart index f0953624c7..2225c811e1 100644 --- a/packages/dart/test/sentry_envelope_test.dart +++ b/packages/dart/test/sentry_envelope_test.dart @@ -209,6 +209,37 @@ void main() { expect(actualItem, expectedItem); }); + test('fromMetricsData creates envelope with wrapped metrics payload', + () async { + final encodedMetrics = [ + utf8.encode( + '{"timestamp":1672531200.0,"type":"counter","name":"metric1","value":1,"trace_id":"abc"}'), + utf8.encode( + '{"timestamp":1672531201.0,"type":"gauge","name":"metric2","value":42,"trace_id":"def"}'), + ]; + + final sdkVersion = + SdkVersion(name: 'fixture-name', version: 'fixture-version'); + final sut = SentryEnvelope.fromMetricsData(encodedMetrics, sdkVersion); + + expect(sut.header.eventId, null); + expect(sut.header.sdkVersion, sdkVersion); + expect(sut.items.length, 1); + + expect(sut.items[0].header.contentType, + 'application/vnd.sentry.items.trace-metric+json'); + expect(sut.items[0].header.type, SentryItemType.metric); + expect(sut.items[0].header.itemCount, 2); + + final actualItem = await sut.items[0].dataFactory(); + final expectedPayload = utf8.encode('{"items":[') + + encodedMetrics[0] + + utf8.encode(',') + + encodedMetrics[1] + + utf8.encode(']}'); + expect(actualItem, expectedPayload); + }); + test('max attachment size', () async { final attachment = SentryAttachment.fromLoader( loader: () => Uint8List.fromList([1, 2, 3, 4]), diff --git a/packages/dart/test/sentry_options_test.dart b/packages/dart/test/sentry_options_test.dart index 25402e2f74..cb20034987 100644 --- a/packages/dart/test/sentry_options_test.dart +++ b/packages/dart/test/sentry_options_test.dart @@ -183,4 +183,10 @@ void main() { expect(() => options.parsedDsn, throwsA(isA())); }); + + test('enableMetrics is true by default', () { + final options = defaultTestOptions(); + + expect(options.enableMetrics, true); + }); } diff --git a/packages/dart/test/sentry_test.dart b/packages/dart/test/sentry_test.dart index ffb609b062..ab688fdfd7 100644 --- a/packages/dart/test/sentry_test.dart +++ b/packages/dart/test/sentry_test.dart @@ -8,6 +8,7 @@ import 'package:sentry/src/dart_exception_type_identifier.dart'; import 'package:sentry/src/event_processor/deduplication_event_processor.dart'; import 'package:sentry/src/logs_enricher_integration.dart'; import 'package:sentry/src/feature_flags_integration.dart'; +import 'package:sentry/src/telemetry/metric/metrics_setup_integration.dart'; import 'package:sentry/src/telemetry/processing/processor_integration.dart'; import 'package:test/test.dart'; @@ -268,6 +269,27 @@ void main() { expect(integration.callCalls, 1); }); + test('should add $MetricsSetupIntegration', () async { + late SentryOptions optionsReference; + final options = defaultTestOptions(); + + await Sentry.init( + options: options, + (options) { + options.dsn = fakeDsn; + optionsReference = options; + }, + appRunner: appRunner, + ); + + expect( + optionsReference.integrations + .whereType() + .length, + 1, + ); + }); + test('should add default integrations', () async { late SentryOptions optionsReference; final options = defaultTestOptions(); @@ -355,7 +377,7 @@ void main() { ); }, onPlatform: {'vm': Skip()}); - test('should add feature flag FeatureFlagsIntegration', () async { + test('should add feature flag $FeatureFlagsIntegration', () async { await Sentry.init( options: defaultTestOptions(), (options) => options.dsn = fakeDsn, diff --git a/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart b/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart new file mode 100644 index 0000000000..e60f63d0e6 --- /dev/null +++ b/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart @@ -0,0 +1,223 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/client_reports/discard_reason.dart'; +import 'package:sentry/src/telemetry/metric/metric_capture_pipeline.dart'; +import 'package:sentry/src/transport/data_category.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mock_client_report_recorder.dart'; +import '../../mocks/mock_telemetry_processor.dart'; +import '../../test_utils.dart'; + +void main() { + group('$MetricCapturePipeline', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('when capturing a metric', () { + test('forwards to telemetry processor', () async { + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(fixture.processor.addedMetrics.length, 1); + expect(fixture.processor.addedMetrics.first, same(metric)); + }); + + test('adds default attributes', () async { + await fixture.scope.setUser(SentryUser(id: 'user-id')); + fixture.scope.setAttributes({ + 'scope-key': SentryAttribute.string('scope-value'), + }); + + final metric = fixture.createMetric() + ..attributes['custom'] = SentryAttribute.string('metric-value'); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + final attributes = metric.attributes; + expect(attributes['scope-key']?.value, 'scope-value'); + expect(attributes['custom']?.value, 'metric-value'); + expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, + 'test-env'); + expect(attributes[SemanticAttributesConstants.sentryRelease]?.value, + 'test-release'); + expect(attributes[SemanticAttributesConstants.sentrySdkName]?.value, + fixture.options.sdk.name); + expect(attributes[SemanticAttributesConstants.sentrySdkVersion]?.value, + fixture.options.sdk.version); + expect( + attributes[SemanticAttributesConstants.userId]?.value, 'user-id'); + }); + + test('prefers scope attributes over defaults', () async { + fixture.scope.setAttributes({ + SemanticAttributesConstants.sentryEnvironment: + SentryAttribute.string('scope-env'), + }); + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + final attributes = metric.attributes; + expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, + 'scope-env'); + expect(attributes[SemanticAttributesConstants.sentryRelease]?.value, + 'test-release'); + }); + + test( + 'dispatches OnProcessMetric after scope merge but before beforeSendMetric', + () async { + final operations = []; + bool hasScopeAttrInCallback = false; + + fixture.scope.setAttributes({ + 'scope-attr': SentryAttribute.string('scope-value'), + }); + + fixture.options.lifecycleRegistry + .registerCallback((event) { + operations.add('onProcessMetric'); + hasScopeAttrInCallback = + event.metric.attributes.containsKey('scope-attr'); + }); + + fixture.options.beforeSendMetric = (metric) { + operations.add('beforeSendMetric'); + return metric; + }; + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(operations, ['onProcessMetric', 'beforeSendMetric']); + expect(hasScopeAttrInCallback, isTrue); + }); + + test('keeps attributes added by lifecycle callbacks', () async { + fixture.options.lifecycleRegistry + .registerCallback((event) { + event.metric.attributes['callback-key'] = + SentryAttribute.string('callback-value'); + event.metric + .attributes[SemanticAttributesConstants.sentryEnvironment] = + SentryAttribute.string('callback-env'); + }); + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + final attributes = metric.attributes; + expect(attributes['callback-key']?.value, 'callback-value'); + expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, + 'callback-env'); + }); + + test('does not add user attributes when sendDefaultPii is false', + () async { + fixture.options.sendDefaultPii = false; + await fixture.scope.setUser(SentryUser(id: 'user-id')); + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect( + metric.attributes.containsKey(SemanticAttributesConstants.userId), + isFalse, + ); + }); + }); + + group('when metrics are disabled', () { + test('does not add metrics to processor', () async { + fixture.options.enableMetrics = false; + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(fixture.processor.addedMetrics, isEmpty); + }); + }); + + group('when beforeSendMetric is configured', () { + test('returning null drops the metric', () async { + fixture.options.beforeSendMetric = (_) => null; + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(fixture.processor.addedMetrics, isEmpty); + }); + + test('returning null records lost event in client report', () async { + fixture.options.beforeSendMetric = (_) => null; + + final metric = fixture.createMetric(); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(fixture.recorder.discardedEvents.length, 1); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.beforeSend); + expect(fixture.recorder.discardedEvents.first.category, + DataCategory.metric); + }); + + test('can mutate the metric', () async { + fixture.options.beforeSendMetric = (metric) { + metric.name = 'modified-name'; + metric.attributes['added-key'] = SentryAttribute.string('added'); + return metric; + }; + + final metric = fixture.createMetric(name: 'original-name'); + + await fixture.pipeline.captureMetric(metric, scope: fixture.scope); + + expect(fixture.processor.addedMetrics.length, 1); + final captured = fixture.processor.addedMetrics.first; + expect(captured.name, 'modified-name'); + expect(captured.attributes['added-key']?.value, 'added'); + }); + }); + }); +} + +class Fixture { + final options = defaultTestOptions() + ..environment = 'test-env' + ..release = 'test-release' + ..sendDefaultPii = true + ..enableMetrics = true; + + final processor = MockTelemetryProcessor(); + final recorder = MockClientReportRecorder(); + + late final Scope scope; + late final MetricCapturePipeline pipeline; + + Fixture() { + options.telemetryProcessor = processor; + options.recorder = recorder; + scope = Scope(options); + pipeline = MetricCapturePipeline(options); + } + + SentryMetric createMetric({String name = 'test-metric'}) { + return SentryCounterMetric( + timestamp: DateTime.now().toUtc(), + name: name, + value: 1, + traceId: SentryId.newId(), + ); + } +} diff --git a/packages/dart/test/telemetry/metric/metric_test.dart b/packages/dart/test/telemetry/metric/metric_test.dart new file mode 100644 index 0000000000..472c5772c1 --- /dev/null +++ b/packages/dart/test/telemetry/metric/metric_test.dart @@ -0,0 +1,72 @@ +import 'package:sentry/sentry.dart'; +import 'package:test/test.dart'; + +void main() { + group('SentryMetric toJson', () { + test('serializes all fields correctly', () { + final traceId = SentryId.newId(); + final spanId = SpanId.newId(); + final timestamp = DateTime.utc(2024, 1, 15, 10, 30, 0); + + final metric = SentryCounterMetric( + timestamp: timestamp, + name: 'button_clicks', + value: 5, + traceId: traceId, + spanId: spanId, + unit: 'click', + attributes: {'key': SentryAttribute.string('value')}, + ); + + final json = metric.toJson(); + + expect(json['timestamp'], 1705314600.0); + expect(json['type'], 'counter'); + expect(json['name'], 'button_clicks'); + expect(json['value'], 5); + expect(json['trace_id'], traceId.toString()); + expect(json['span_id'], spanId.toString()); + expect(json['unit'], 'click'); + expect(json['attributes']['key'], {'type': 'string', 'value': 'value'}); + }); + + test('omits optional fields when null', () { + final metric = SentryCounterMetric( + timestamp: DateTime.utc(2024, 1, 15), + name: 'test', + value: 1, + traceId: SentryId.newId(), + ); + + final json = metric.toJson(); + + expect(json.containsKey('span_id'), isFalse); + expect(json.containsKey('unit'), isFalse); + expect(json.containsKey('attributes'), isFalse); + }); + + test('each metric type sets correct type field', () { + final traceId = SentryId.newId(); + final timestamp = DateTime.utc(2024, 1, 15); + + expect( + SentryCounterMetric( + timestamp: timestamp, name: 't', value: 1, traceId: traceId) + .toJson()['type'], + 'counter', + ); + expect( + SentryGaugeMetric( + timestamp: timestamp, name: 't', value: 1, traceId: traceId) + .toJson()['type'], + 'gauge', + ); + expect( + SentryDistributionMetric( + timestamp: timestamp, name: 't', value: 1, traceId: traceId) + .toJson()['type'], + 'distribution', + ); + }); + }); +} diff --git a/packages/dart/test/telemetry/metric/metrics_setup_integration_test.dart b/packages/dart/test/telemetry/metric/metrics_setup_integration_test.dart new file mode 100644 index 0000000000..5dc7aef1d2 --- /dev/null +++ b/packages/dart/test/telemetry/metric/metrics_setup_integration_test.dart @@ -0,0 +1,95 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/metric/default_metrics.dart'; +import 'package:sentry/src/telemetry/metric/metrics_setup_integration.dart'; +import 'package:sentry/src/telemetry/metric/noop_metrics.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + group('$MetricsSetupIntegration', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('when metrics are enabled', () { + test('configures DefaultSentryMetrics', () { + fixture.options.enableMetrics = true; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.metrics, isA()); + }); + + test('adds integration to SDK', () { + fixture.options.enableMetrics = true; + + fixture.sut.call(fixture.hub, fixture.options); + + expect( + fixture.options.sdk.integrations, + contains(MetricsSetupIntegration.integrationName), + ); + }); + + test('does not override existing non-noop metrics', () { + fixture.options.enableMetrics = true; + final customMetrics = _CustomSentryMetrics(); + fixture.options.metrics = customMetrics; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.metrics, same(customMetrics)); + }); + }); + + group('when metrics are disabled', () { + test('does not configure metrics', () { + fixture.options.enableMetrics = false; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.metrics, isA()); + }); + + test('does not add integration to SDK', () { + fixture.options.enableMetrics = false; + + fixture.sut.call(fixture.hub, fixture.options); + + expect( + fixture.options.sdk.integrations, + isNot(contains(MetricsSetupIntegration.integrationName)), + ); + }); + }); + }); +} + +class Fixture { + final options = defaultTestOptions(); + + late final Hub hub; + late final MetricsSetupIntegration sut; + + Fixture() { + hub = Hub(options); + sut = MetricsSetupIntegration(); + } +} + +class _CustomSentryMetrics implements SentryMetrics { + @override + void count(String name, int value, + {Map? attributes, Scope? scope}) {} + + @override + void distribution(String name, num value, + {String? unit, Map? attributes, Scope? scope}) {} + + @override + void gauge(String name, num value, + {String? unit, Map? attributes, Scope? scope}) {} +} diff --git a/packages/dart/test/telemetry/metric/metrics_test.dart b/packages/dart/test/telemetry/metric/metrics_test.dart new file mode 100644 index 0000000000..68ab5a9b5e --- /dev/null +++ b/packages/dart/test/telemetry/metric/metrics_test.dart @@ -0,0 +1,151 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/metric/default_metrics.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + group('$DefaultSentryMetrics', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('when calling count', () { + test('creates counter metric with correct type', () { + fixture.sut.count('test-counter', 5); + + expect(fixture.capturedMetrics.length, 1); + final metric = fixture.capturedMetrics.first; + expect(metric, isA()); + expect(metric.type, 'counter'); + }); + + test('sets name and value', () { + fixture.sut.count('my-counter', 42); + + final metric = fixture.capturedMetrics.first; + expect(metric.name, 'my-counter'); + expect(metric.value, 42); + }); + + test('includes attributes when provided', () { + fixture.sut.count( + 'test-counter', + 1, + attributes: {'key': SentryAttribute.string('value')}, + ); + + final metric = fixture.capturedMetrics.first; + expect(metric.attributes['key']?.value, 'value'); + }); + + test('sets trace id from scope', () { + fixture.sut.count('test-counter', 1); + + final metric = fixture.capturedMetrics.first; + expect(metric.traceId, fixture.scope.propagationContext.traceId); + }); + + test('sets timestamp from clock', () { + fixture.sut.count('test-counter', 1); + + final metric = fixture.capturedMetrics.first; + expect(metric.timestamp, fixture.fixedTimestamp); + }); + }); + + group('when calling gauge', () { + test('creates gauge metric with correct type', () { + fixture.sut.gauge('test-gauge', 42.5); + + expect(fixture.capturedMetrics.length, 1); + final metric = fixture.capturedMetrics.first; + expect(metric, isA()); + expect(metric.type, 'gauge'); + }); + + test('sets name and value', () { + fixture.sut.gauge('memory-usage', 75.5); + + final metric = fixture.capturedMetrics.first; + expect(metric.name, 'memory-usage'); + expect(metric.value, 75.5); + }); + + test('includes unit when provided', () { + fixture.sut.gauge('response-time', 250, unit: 'millisecond'); + + final metric = fixture.capturedMetrics.first; + expect(metric.unit, 'millisecond'); + }); + + test('includes attributes when provided', () { + fixture.sut.gauge( + 'test-gauge', + 10, + attributes: {'env': SentryAttribute.string('prod')}, + ); + + final metric = fixture.capturedMetrics.first; + expect(metric.attributes['env']?.value, 'prod'); + }); + }); + + group('when calling distribution', () { + test('creates distribution metric with correct type', () { + fixture.sut.distribution('test-distribution', 100); + + expect(fixture.capturedMetrics.length, 1); + final metric = fixture.capturedMetrics.first; + expect(metric, isA()); + expect(metric.type, 'distribution'); + }); + + test('sets name and value', () { + fixture.sut.distribution('response-time', 250); + + final metric = fixture.capturedMetrics.first; + expect(metric.name, 'response-time'); + expect(metric.value, 250); + }); + + test('includes unit when provided', () { + fixture.sut.distribution('response-time', 250, unit: 'millisecond'); + + final metric = fixture.capturedMetrics.first; + expect(metric.unit, 'millisecond'); + }); + + test('includes attributes when provided', () { + fixture.sut.distribution( + 'test-distribution', + 50, + attributes: {'route': SentryAttribute.string('/api/users')}, + ); + + final metric = fixture.capturedMetrics.first; + expect(metric.attributes['route']?.value, '/api/users'); + }); + }); + }); +} + +class Fixture { + final options = defaultTestOptions(); + final capturedMetrics = []; + final fixedTimestamp = DateTime.utc(2024, 1, 15, 10, 30, 0); + + late final Scope scope; + late final DefaultSentryMetrics sut; + + Fixture() { + scope = Scope(options); + sut = DefaultSentryMetrics( + captureMetricCallback: (metric) async => capturedMetrics.add(metric), + clockProvider: () => fixedTimestamp, + scopeProvider: () => scope, + ); + } +} diff --git a/packages/dart/test/telemetry/processing/processor_test.dart b/packages/dart/test/telemetry/processing/processor_test.dart index 64b8476d1b..46fefd0299 100644 --- a/packages/dart/test/telemetry/processing/processor_test.dart +++ b/packages/dart/test/telemetry/processing/processor_test.dart @@ -36,22 +36,44 @@ void main() { }); }); + group('addMetric', () { + test('routes metric to metric buffer', () { + final mockMetricBuffer = MockTelemetryBuffer(); + final processor = + fixture.getSut(enableMetrics: true, metricBuffer: mockMetricBuffer); + + final metric = fixture.createMetric(); + processor.addMetric(metric); + + expect(mockMetricBuffer.addedItems.length, 1); + expect(mockMetricBuffer.addedItems.first, metric); + }); + }); + group('flush', () { test('flushes all registered buffers', () async { final mockLogBuffer = MockTelemetryBuffer(); + final mockMetricBuffer = MockTelemetryBuffer(); + final processor = fixture.getSut( enableLogs: true, logBuffer: mockLogBuffer, + metricBuffer: mockMetricBuffer, ); await processor.flush(); expect(mockLogBuffer.flushCallCount, 1); + expect(mockMetricBuffer.flushCallCount, 1); }); test('returns sync (null) when all buffers flush synchronously', () { final mockLogBuffer = MockTelemetryBuffer(asyncFlush: false); - final processor = fixture.getSut(logBuffer: mockLogBuffer); + final mockMetricBuffer = + MockTelemetryBuffer(asyncFlush: false); + + final processor = fixture.getSut( + logBuffer: mockLogBuffer, metricBuffer: mockMetricBuffer); final result = processor.flush(); @@ -61,7 +83,10 @@ void main() { test('returns Future when at least one buffer flushes asynchronously', () async { final mockLogBuffer = MockTelemetryBuffer(asyncFlush: true); - final processor = fixture.getSut(logBuffer: mockLogBuffer); + final mockMetricBuffer = + MockTelemetryBuffer(asyncFlush: false); + final processor = fixture.getSut( + logBuffer: mockLogBuffer, metricBuffer: mockMetricBuffer); final result = processor.flush(); @@ -81,12 +106,14 @@ class Fixture { DefaultTelemetryProcessor getSut({ bool enableLogs = false, + bool enableMetrics = false, MockTelemetryBuffer? logBuffer, + MockTelemetryBuffer? metricBuffer, }) { options.enableLogs = enableLogs; + options.enableMetrics = enableMetrics; return DefaultTelemetryProcessor( - logBuffer: logBuffer, - ); + logBuffer: logBuffer, metricBuffer: metricBuffer); } SentryLog createLog({String body = 'test log'}) { @@ -97,4 +124,12 @@ class Fixture { attributes: {}, ); } + + SentryMetric createMetric() => SentryCounterMetric( + timestamp: DateTime.now().toUtc(), + attributes: {}, + name: 'test-metric', + value: 1, + traceId: SentryId.newId(), + ); } diff --git a/packages/flutter/example/integration_test/platform_integrations_test.dart b/packages/flutter/example/integration_test/platform_integrations_test.dart index 75c675e754..a76cd94cc6 100644 --- a/packages/flutter/example/integration_test/platform_integrations_test.dart +++ b/packages/flutter/example/integration_test/platform_integrations_test.dart @@ -14,7 +14,7 @@ import 'package:sentry_flutter/src/integrations/generic_app_start_integration.da import 'package:sentry_flutter/src/integrations/load_contexts_integration.dart'; import 'package:sentry_flutter/src/integrations/native_load_debug_images_integration.dart'; import 'package:sentry_flutter/src/integrations/native_sdk_integration.dart'; -import 'package:sentry_flutter/src/integrations/replay_log_integration.dart'; +import 'package:sentry_flutter/src/integrations/replay_telemetry_integration.dart'; import 'package:sentry_flutter/src/integrations/screenshot_integration.dart'; import 'package:sentry_flutter/src/integrations/thread_info_integration.dart'; import 'package:sentry_flutter/src/integrations/web_session_integration.dart'; @@ -162,14 +162,16 @@ void main() { isTrue); expect( options.integrations.any((i) => i is ReplayIntegration), isTrue); - expect(options.integrations.any((i) => i is ReplayLogIntegration), + expect( + options.integrations.any((i) => i is ReplayTelemetryIntegration), isTrue); } else if (isIOS) { expect(options.integrations.any((i) => i is LoadContextsIntegration), isTrue); expect( options.integrations.any((i) => i is ReplayIntegration), isTrue); - expect(options.integrations.any((i) => i is ReplayLogIntegration), + expect( + options.integrations.any((i) => i is ReplayTelemetryIntegration), isTrue); } else if (isMacOS) { expect(options.integrations.any((i) => i is LoadContextsIntegration), @@ -180,7 +182,8 @@ void main() { // still not add it expect( options.integrations.any((i) => i is ReplayIntegration), isTrue); - expect(options.integrations.any((i) => i is ReplayLogIntegration), + expect( + options.integrations.any((i) => i is ReplayTelemetryIntegration), isFalse); } }); @@ -235,7 +238,7 @@ void main() { isFalse); expect( options.integrations.any((i) => i is ReplayIntegration), isFalse); - expect(options.integrations.any((i) => i is ReplayLogIntegration), + expect(options.integrations.any((i) => i is ReplayTelemetryIntegration), isFalse); // Ordering: RunZonedGuarded before Widgets diff --git a/packages/flutter/example/lib/main.dart b/packages/flutter/example/lib/main.dart index d1e2a18fef..fc73988b02 100644 --- a/packages/flutter/example/lib/main.dart +++ b/packages/flutter/example/lib/main.dart @@ -97,6 +97,13 @@ Future setupSentry( options.enableLogs = true; + options.beforeSendMetric = (metric) { + if (metric.name == 'drop-metric') { + return null; + } + return metric; + }; + _isIntegrationTest = isIntegrationTest; if (_isIntegrationTest) { options.dist = '1'; @@ -544,6 +551,37 @@ class MainScaffold extends StatelessWidget { text: 'Demonstrates the feature flags.', buttonTitle: 'Add "feature-one" flag', ), + TooltipButton( + onPressed: () { + Sentry.metrics.count( + 'screen.view', + 1, + attributes: { + 'screen': SentryAttribute.string('HomeScreen'), + 'source': SentryAttribute.string('navigation'), + }, + ); + Sentry.metrics.gauge( + 'app.memory_usage', + 128, + unit: 'megabyte', + attributes: { + 'state': SentryAttribute.string('foreground'), + }, + ); + Sentry.metrics.distribution( + 'ui.render_time', + 16.7, + unit: 'millisecond', + attributes: { + 'widget': SentryAttribute.string('ListView'), + 'item_count': SentryAttribute.int(50), + }, + ); + }, + text: 'Demonstrates Sentry Metrics.', + buttonTitle: 'Send Metrics', + ), TooltipButton( onPressed: () { Sentry.logger diff --git a/packages/flutter/lib/src/integrations/load_contexts_integration.dart b/packages/flutter/lib/src/integrations/load_contexts_integration.dart index fa9b625ab5..3d4791d5b1 100644 --- a/packages/flutter/lib/src/integrations/load_contexts_integration.dart +++ b/packages/flutter/lib/src/integrations/load_contexts_integration.dart @@ -1,13 +1,14 @@ +// ignore_for_file: implementation_imports, invalid_use_of_internal_member + import 'dart:async'; import 'package:sentry/sentry.dart'; import 'package:collection/collection.dart'; -// ignore: implementation_imports import 'package:sentry/src/event_processor/enricher/enricher_event_processor.dart'; -// ignore: implementation_imports import 'package:sentry/src/logs_enricher_integration.dart'; import '../native/sentry_native_binding.dart'; import '../sentry_flutter_options.dart'; +import '../utils/internal_logger.dart'; /// Load Device's Contexts from the iOS & Android SDKs. /// @@ -19,13 +20,19 @@ import '../sentry_flutter_options.dart'; /// App, Device and OS. /// /// This integration is only executed on iOS, macOS & Android Apps. -class LoadContextsIntegration extends Integration { +class LoadContextsIntegration implements Integration { final SentryNativeBinding _native; + Map? _cachedAttributes; + SentryFlutterOptions? _options; + SdkLifecycleCallback? _logCallback; + SdkLifecycleCallback? _metricCallback; LoadContextsIntegration(this._native); @override void call(Hub hub, SentryFlutterOptions options) { + _options = options; + options.addEventProcessor( _LoadContextsIntegrationEventProcessor(_native, options), ); @@ -45,7 +52,6 @@ class LoadContextsIntegration extends Integration { } if (options.enableLogs) { final logsEnricherIntegration = options.integrations.firstWhereOrNull( - // ignore: invalid_use_of_internal_member (element) => element is LogsEnricherIntegration, ); if (logsEnricherIntegration != null) { @@ -54,55 +60,99 @@ class LoadContextsIntegration extends Integration { options.removeIntegration(logsEnricherIntegration); } - // ignore: invalid_use_of_internal_member + _logCallback = (event) async { + try { + final attributes = await _nativeContextAttributes(); + event.log.attributes.addAllIfAbsent(attributes); + } catch (exception, stackTrace) { + internalLogger.error( + 'LoadContextsIntegration failed to load contexts for $OnBeforeCaptureLog', + error: exception, + stackTrace: stackTrace, + ); + } + }; options.lifecycleRegistry.registerCallback( - (event) async { - try { - final infos = await _native.loadContexts() ?? {}; - - final contextsMap = infos['contexts'] as Map?; - final contexts = - Contexts(); // We just need the the native contexts. - _mergeNativeWithLocalContexts(contextsMap, contexts); - - if (contexts.operatingSystem?.name != null) { - event.log.attributes['os.name'] = SentryAttribute.string( - contexts.operatingSystem?.name ?? '', - ); - } - if (contexts.operatingSystem?.version != null) { - event.log.attributes['os.version'] = SentryAttribute.string( - contexts.operatingSystem?.version ?? '', - ); - } - if (contexts.device?.brand != null) { - event.log.attributes['device.brand'] = SentryAttribute.string( - contexts.device?.brand ?? '', - ); - } - if (contexts.device?.model != null) { - event.log.attributes['device.model'] = SentryAttribute.string( - contexts.device?.model ?? '', - ); - } - if (contexts.device?.family != null) { - event.log.attributes['device.family'] = SentryAttribute.string( - contexts.device?.family ?? '', - ); - } - } catch (exception, stackTrace) { - options.log( - SentryLevel.error, - 'LoadContextsIntegration failed to load contexts', - exception: exception, - stackTrace: stackTrace, - ); - } - }, + _logCallback!, + ); + } + + if (options.enableMetrics) { + _metricCallback = (event) async { + try { + final attributes = await _nativeContextAttributes(); + event.metric.attributes.addAllIfAbsent(attributes); + } catch (exception, stackTrace) { + internalLogger.error( + 'LoadContextsIntegration failed to load contexts for $OnProcessMetric', + error: exception, + stackTrace: stackTrace, + ); + } + }; + options.lifecycleRegistry.registerCallback( + _metricCallback!, ); } + options.sdk.addIntegration('loadContextsIntegration'); } + + @override + void close() { + final options = _options; + if (options == null) return; + + if (_logCallback != null) { + options.lifecycleRegistry + .removeCallback(_logCallback!); + _logCallback = null; + } + if (_metricCallback != null) { + options.lifecycleRegistry + .removeCallback(_metricCallback!); + _metricCallback = null; + } + _cachedAttributes = null; + } + + Future> _nativeContextAttributes() async { + if (_cachedAttributes != null) { + return _cachedAttributes!; + } + + final nativeContexts = await _native.loadContexts() ?? {}; + + final contextsMap = nativeContexts['contexts'] as Map?; + final contexts = Contexts(); + _mergeNativeWithLocalContexts(contextsMap, contexts); + + final attributes = {}; + if (contexts.operatingSystem?.name != null) { + attributes[SemanticAttributesConstants.osName] = + SentryAttribute.string(contexts.operatingSystem!.name!); + } + if (contexts.operatingSystem?.version != null) { + attributes[SemanticAttributesConstants.osVersion] = + SentryAttribute.string(contexts.operatingSystem!.version!); + } + if (contexts.device?.brand != null) { + attributes[SemanticAttributesConstants.deviceBrand] = + SentryAttribute.string(contexts.device!.brand!); + } + if (contexts.device?.model != null) { + attributes[SemanticAttributesConstants.deviceModel] = + SentryAttribute.string(contexts.device!.model!); + } + if (contexts.device?.family != null) { + attributes[SemanticAttributesConstants.deviceFamily] = + SentryAttribute.string(contexts.device!.family!); + } + + _cachedAttributes = attributes; + + return attributes; + } } class _LoadContextsIntegrationEventProcessor implements EventProcessor { @@ -247,10 +297,9 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { event.tags = tags; } } catch (exception, stackTrace) { - _options.log( - SentryLevel.error, + internalLogger.error( 'loadContextsIntegration failed', - exception: exception, + error: exception, stackTrace: stackTrace, ); if (_options.automatedTestMode) { diff --git a/packages/flutter/lib/src/integrations/replay_log_integration.dart b/packages/flutter/lib/src/integrations/replay_log_integration.dart deleted file mode 100644 index 2747930cdd..0000000000 --- a/packages/flutter/lib/src/integrations/replay_log_integration.dart +++ /dev/null @@ -1,63 +0,0 @@ -// ignore_for_file: invalid_use_of_internal_member - -import 'package:sentry/sentry.dart'; -import '../sentry_flutter_options.dart'; -import '../native/sentry_native_binding.dart'; - -/// Integration that adds replay-related information to logs using lifecycle callbacks -class ReplayLogIntegration implements Integration { - static const String integrationName = 'ReplayLog'; - - final SentryNativeBinding? _native; - ReplayLogIntegration(this._native); - - SentryFlutterOptions? _options; - SdkLifecycleCallback? _addReplayInformation; - - @override - Future call(Hub hub, SentryFlutterOptions options) async { - if (!options.replay.isEnabled) { - return; - } - final sessionSampleRate = options.replay.sessionSampleRate ?? 0; - final onErrorSampleRate = options.replay.onErrorSampleRate ?? 0; - - _options = options; - _addReplayInformation = (OnBeforeCaptureLog event) { - final scopeReplayId = hub.scope.replayId; - final replayId = scopeReplayId ?? _native?.replayId; - final replayIsBuffering = replayId != null && scopeReplayId == null; - - if (sessionSampleRate > 0 && replayId != null && !replayIsBuffering) { - event.log.attributes['sentry.replay_id'] = SentryAttribute.string( - scopeReplayId.toString(), - ); - } else if (onErrorSampleRate > 0 && - replayId != null && - replayIsBuffering) { - event.log.attributes['sentry.replay_id'] = SentryAttribute.string( - replayId.toString(), - ); - event.log.attributes['sentry._internal.replay_is_buffering'] = - SentryAttribute.bool(true); - } - }; - options.lifecycleRegistry - .registerCallback(_addReplayInformation!); - options.sdk.addIntegration(integrationName); - } - - @override - Future close() async { - final options = _options; - final addReplayInformation = _addReplayInformation; - - if (options != null && addReplayInformation != null) { - options.lifecycleRegistry - .removeCallback(addReplayInformation); - } - - _options = null; - _addReplayInformation = null; - } -} diff --git a/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart b/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart new file mode 100644 index 0000000000..4883ad1bb1 --- /dev/null +++ b/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart @@ -0,0 +1,97 @@ +// ignore_for_file: invalid_use_of_internal_member + +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; +import '../sentry_flutter_options.dart'; +import '../native/sentry_native_binding.dart'; + +/// Integration that adds replay-related information to logs and metrics +/// using lifecycle callbacks. +@internal +class ReplayTelemetryIntegration implements Integration { + static const String integrationName = 'ReplayTelemetry'; + + final SentryNativeBinding? _native; + ReplayTelemetryIntegration(this._native); + + SentryFlutterOptions? _options; + SdkLifecycleCallback? _onBeforeCaptureLog; + SdkLifecycleCallback? _onProcessMetric; + + @override + Future call(Hub hub, SentryFlutterOptions options) async { + if (!options.replay.isEnabled) { + return; + } + final sessionSampleRate = options.replay.sessionSampleRate ?? 0; + final onErrorSampleRate = options.replay.onErrorSampleRate ?? 0; + + _options = options; + + _onBeforeCaptureLog = (OnBeforeCaptureLog event) { + _addReplayAttributes( + hub.scope.replayId, + event.log.attributes, + sessionSampleRate: sessionSampleRate, + onErrorSampleRate: onErrorSampleRate, + ); + }; + + _onProcessMetric = (OnProcessMetric event) { + _addReplayAttributes( + hub.scope.replayId, + event.metric.attributes, + sessionSampleRate: sessionSampleRate, + onErrorSampleRate: onErrorSampleRate, + ); + }; + + options.lifecycleRegistry + .registerCallback(_onBeforeCaptureLog!); + options.lifecycleRegistry + .registerCallback(_onProcessMetric!); + options.sdk.addIntegration(integrationName); + } + + void _addReplayAttributes( + SentryId? scopeReplayId, + Map attributes, { + required double sessionSampleRate, + required double onErrorSampleRate, + }) { + final replayId = scopeReplayId ?? _native?.replayId; + final replayIsBuffering = replayId != null && scopeReplayId == null; + + if (sessionSampleRate > 0 && replayId != null && !replayIsBuffering) { + attributes[SemanticAttributesConstants.sentryReplayId] = + SentryAttribute.string(scopeReplayId.toString()); + } else if (onErrorSampleRate > 0 && replayId != null && replayIsBuffering) { + attributes[SemanticAttributesConstants.sentryReplayId] = + SentryAttribute.string(replayId.toString()); + attributes[SemanticAttributesConstants.sentryInternalReplayIsBuffering] = + SentryAttribute.bool(true); + } + } + + @override + Future close() async { + final options = _options; + final onBeforeCaptureLog = _onBeforeCaptureLog; + final onProcessMetric = _onProcessMetric; + + if (options != null) { + if (onBeforeCaptureLog != null) { + options.lifecycleRegistry + .removeCallback(onBeforeCaptureLog); + } + if (onProcessMetric != null) { + options.lifecycleRegistry + .removeCallback(onProcessMetric); + } + } + + _options = null; + _onBeforeCaptureLog = null; + _onProcessMetric = null; + } +} diff --git a/packages/flutter/lib/src/sentry_flutter.dart b/packages/flutter/lib/src/sentry_flutter.dart index 0609d087bf..3ec4d43cd9 100644 --- a/packages/flutter/lib/src/sentry_flutter.dart +++ b/packages/flutter/lib/src/sentry_flutter.dart @@ -22,7 +22,7 @@ import 'integrations/flutter_framework_feature_flag_integration.dart'; import 'integrations/frames_tracking_integration.dart'; import 'integrations/integrations.dart'; import 'integrations/native_app_start_handler.dart'; -import 'integrations/replay_log_integration.dart'; +import 'integrations/replay_telemetry_integration.dart'; import 'integrations/screenshot_integration.dart'; import 'integrations/generic_app_start_integration.dart'; import 'integrations/thread_info_integration.dart'; @@ -232,9 +232,9 @@ mixin SentryFlutter { integrations.add(DebugPrintIntegration()); - // Only add ReplayLogIntegration on platforms that support replay + // Only add ReplayTelemetryIntegration on platforms that support replay if (native != null && native.supportsReplay) { - integrations.add(ReplayLogIntegration(native)); + integrations.add(ReplayTelemetryIntegration(native)); } if (!platform.isWeb) { diff --git a/packages/flutter/test/integrations/load_contexts_integration_test.dart b/packages/flutter/test/integrations/load_contexts_integration_test.dart index 4dd6c5b00b..5c07b1648a 100644 --- a/packages/flutter/test/integrations/load_contexts_integration_test.dart +++ b/packages/flutter/test/integrations/load_contexts_integration_test.dart @@ -1,27 +1,57 @@ @TestOn('vm') library; +// ignore_for_file: invalid_use_of_internal_member + import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; +import 'package:sentry/src/logs_enricher_integration.dart'; import 'package:sentry/src/sentry_tracer.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/integrations/load_contexts_integration.dart'; + import 'fixture.dart'; -import 'package:sentry/src/logs_enricher_integration.dart'; void main() { - final infosJson = { + final defaultContexts = { + 'integrations': ['NativeIntegration'], + 'package': {'sdk_name': 'native-package', 'version': '1.0'}, 'contexts': { 'device': { + 'name': 'Device1', 'family': 'fixture-device-family', 'model': 'fixture-device-model', 'brand': 'fixture-device-brand', }, + 'app': {'app_name': 'test-app'}, 'os': { 'name': 'fixture-os-name', 'version': 'fixture-os-version', }, - } + 'gpu': {'name': 'gpu1'}, + 'browser': {'name': 'browser1'}, + 'runtime': {'name': 'RT1'}, + 'theme': 'material', + }, + 'user': { + 'id': '196E065A-AAF7-409A-9A6C-A81F40274CB9', + 'username': 'fixture-username', + 'email': 'fixture-email', + 'ip_address': 'fixture-ip_address', + 'data': {'key': 'value'}, + }, + 'tags': {'key-a': 'native', 'key-b': 'native'}, + 'extra': {'key-a': 'native', 'key-b': 'native'}, + 'dist': 'fixture-dist', + 'environment': 'fixture-environment', + 'fingerprint': ['fingerprint-a'], + 'level': 'error', + 'breadcrumbs': [ + { + 'timestamp': '1970-01-01T00:00:00.000Z', + 'message': 'native-crumb', + } + ] }; SentryLog givenLog() { @@ -36,290 +66,811 @@ void main() { ); } + SdkVersion getSdkVersion({ + String name = 'sentry.dart', + List integrations = const [], + List packages = const [], + }) { + return SdkVersion( + name: name, + version: '1.0', + integrations: integrations, + packages: packages, + ); + } + + SentryEvent getEvent({ + SdkVersion? sdk, + Map? tags, + Map? extra, + SentryUser? user, + String? dist, + String? environment, + List? fingerprint, + SentryLevel? level, + List? breadcrumbs, + Contexts? contexts, + List integrations = const ['EventIntegration'], + List packages = const [], + }) { + if (packages.isEmpty) { + packages = [SentryPackage('event-package', '2.0')]; + } + return SentryEvent( + sdk: sdk ?? + getSdkVersion( + integrations: integrations, + packages: packages, + ), + tags: tags, + // ignore: deprecated_member_use + extra: extra, + user: user, + dist: dist, + environment: environment, + fingerprint: fingerprint, + level: level, + breadcrumbs: breadcrumbs, + contexts: contexts, + ); + } + group(LoadContextsIntegration, () { - late IntegrationTestFixture fixture; + late IntegrationTestFixture fixture; setUp(() { fixture = IntegrationTestFixture(LoadContextsIntegration.new); + // Default stub - tests can override this + when(fixture.binding.loadContexts()).thenAnswer((_) async => null); }); - test('loadContextsIntegration adds integration', () async { + void mockLoadContexts([Map? contexts]) { + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => contexts ?? defaultContexts); + } + + test('adds integration to sdk.integrations', () async { await fixture.registerIntegration(); expect( - fixture.options.sdk.integrations.contains('loadContextsIntegration'), - true); + fixture.options.sdk.integrations.contains('loadContextsIntegration'), + true, + ); }); - test('take breadcrumbs from native if scope sync is enabled', () async { + test('applies loadContextsIntegration eventProcessor', () async { + mockLoadContexts(); await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - - final eventBreadcrumb = Breadcrumb(message: 'event'); - var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); + expect(fixture.options.eventProcessors.length, 1); - when(fixture.binding.loadContexts()).thenAnswer((_) async => { - 'breadcrumbs': [Breadcrumb(message: 'native').toJson()] - }); + final e = SentryEvent(); + e.contexts.operatingSystem = SentryOperatingSystem(theme: 'theme1'); + e.contexts.app = SentryApp(inForeground: true); - event = - (await fixture.options.eventProcessors.first.apply(event, Hint()))!; + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - expect(event.breadcrumbs!.length, 1); - expect(event.breadcrumbs!.first.message, 'native'); + verify(fixture.binding.loadContexts()).called(1); + expect(event?.contexts.device?.name, 'Device1'); + expect(event?.contexts.app?.name, 'test-app'); + expect(event?.contexts.app?.inForeground, true); + expect(event?.contexts.operatingSystem?.name, 'fixture-os-name'); + expect(event?.contexts.operatingSystem?.theme, 'theme1'); + expect(event?.contexts.gpu?.name, 'gpu1'); + expect(event?.contexts.browser?.name, 'browser1'); + expect(event?.contexts.runtimes.any((element) => element.name == 'RT1'), + true); + expect(event?.contexts['theme'], 'material'); + expect( + event?.sdk?.packages.any((element) => element.name == 'native-package'), + true, + ); + expect(event?.sdk?.integrations.contains('NativeIntegration'), true); + expect(event?.user?.id, '196E065A-AAF7-409A-9A6C-A81F40274CB9'); }); - test('take breadcrumbs from event if scope sync is disabled', () async { + test('does not override event contexts with loadContextsIntegration infos', + () async { + mockLoadContexts(); await fixture.registerIntegration(); - fixture.options.enableScopeSync = false; - - final eventBreadcrumb = Breadcrumb(message: 'event'); - var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); - - when(fixture.binding.loadContexts()).thenAnswer((_) async => { - 'breadcrumbs': [Breadcrumb(message: 'native').toJson()] - }); - event = - (await fixture.options.eventProcessors.first.apply(event, Hint()))!; - - expect(event.breadcrumbs!.length, 1); - expect(event.breadcrumbs!.first.message, 'event'); - }); - - test('apply beforeBreadcrumb to native breadcrumbs', () async { - await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - fixture.options.beforeBreadcrumb = (breadcrumb, hint) { - if (breadcrumb?.message == 'native-mutated') { - breadcrumb?.message = 'native-mutated-applied'; - return breadcrumb; - } else { - return null; - } - }; - - final eventBreadcrumb = Breadcrumb(message: 'event'); - var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); - - when(fixture.binding.loadContexts()).thenAnswer((_) async => { - 'breadcrumbs': [ - Breadcrumb(message: 'native-mutated').toJson(), - Breadcrumb(message: 'native-deleted').toJson(), - ] - }); - - event = - (await fixture.options.eventProcessors.first.apply(event, Hint()))!; - - expect(event.breadcrumbs!.length, 1); - expect(event.breadcrumbs!.first.message, 'native-mutated-applied'); + final eventContexts = Contexts( + device: SentryDevice(name: 'eDevice'), + app: SentryApp(name: 'eApp', inForeground: true), + operatingSystem: SentryOperatingSystem(name: 'eOS'), + gpu: SentryGpu(name: 'eGpu'), + browser: SentryBrowser(name: 'eBrowser'), + runtimes: [SentryRuntime(name: 'eRT')], + )..['theme'] = 'cuppertino'; + + final e = getEvent( + contexts: eventContexts, + user: SentryUser(id: 'myId'), + ); + + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + verify(fixture.binding.loadContexts()).called(1); + expect(event?.contexts.device?.name, 'eDevice'); + expect(event?.contexts.app?.name, 'eApp'); + expect(event?.contexts.app?.inForeground, true); + expect(event?.contexts.operatingSystem?.name, 'eOS'); + expect(event?.contexts.gpu?.name, 'eGpu'); + expect(event?.contexts.browser?.name, 'eBrowser'); + expect(event?.contexts.runtimes.any((element) => element.name == 'RT1'), + true); + expect(event?.contexts.runtimes.any((element) => element.name == 'eRT'), + true); + expect(event?.contexts['theme'], 'cuppertino'); + expect(event?.user?.id, 'myId'); }); test( - 'apply default IP to user during captureEvent after loading context if ip is null and sendDefaultPii is true', + 'merges event and loadContextsIntegration sdk packages and integration', () async { + mockLoadContexts(); await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - fixture.options.sendDefaultPii = true; + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - const expectedIp = '{{auto}}'; - String? actualIp; - - const expectedId = '1'; - String? actualId; + expect( + event?.sdk?.packages.any((element) => element.name == 'native-package'), + true, + ); + expect( + event?.sdk?.packages.any((element) => element.name == 'event-package'), + true, + ); + expect(event?.sdk?.integrations.contains('NativeIntegration'), true); + expect(event?.sdk?.integrations.contains('EventIntegration'), true); + }); - fixture.options.beforeSend = (event, hint) { - actualIp = event.user?.ipAddress; - actualId = event.user?.id; - return event; - }; + test('does not duplicate integration if already there', () async { + mockLoadContexts({ + 'integrations': ['EventIntegration'] + }); + await fixture.registerIntegration(); - final options = fixture.options; + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - final user = SentryUser(id: expectedId); - when(fixture.binding.loadContexts()) - .thenAnswer((_) async => {'user': user.toJson()}); + expect( + event?.sdk?.integrations + .where((element) => element == 'EventIntegration') + .length, + 1, + ); + }); - final client = SentryClient(options); - final event = SentryEvent(); + test('does not duplicate package if already there', () async { + mockLoadContexts({ + 'package': {'sdk_name': 'event-package', 'version': '2.0'} + }); + await fixture.registerIntegration(); - await client.captureEvent(event); + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - expect(actualIp, expectedIp); - expect(actualId, expectedId); + expect( + event?.sdk?.packages + .where((element) => + element.name == 'event-package' && element.version == '2.0') + .length, + 1, + ); }); - test( - 'does not apply default IP to user during captureEvent after loading context if ip is null and sendDefaultPii is false', - () async { + test('adds package if different version', () async { + mockLoadContexts({ + 'package': {'sdk_name': 'event-package', 'version': '3.0'} + }); await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - // sendDefaultPii false is by default - String? actualIp; + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - const expectedId = '1'; - String? actualId; + expect( + event?.sdk?.packages + .where((element) => + element.name == 'event-package' && element.version == '2.0') + .length, + 1, + ); + expect( + event?.sdk?.packages + .where((element) => + element.name == 'event-package' && element.version == '3.0') + .length, + 1, + ); + }); - fixture.options.beforeSend = (event, hint) { - actualIp = event.user?.ipAddress; - actualId = event.user?.id; - return event; - }; + group('breadcrumbs', () { + test('takes breadcrumbs from native if scope sync is enabled', () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + + final eventBreadcrumb = Breadcrumb(message: 'event'); + var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); + + when(fixture.binding.loadContexts()).thenAnswer((_) async => { + 'breadcrumbs': [Breadcrumb(message: 'native').toJson()] + }); + + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; + + expect(event.breadcrumbs!.length, 1); + expect(event.breadcrumbs!.first.message, 'native'); + }); + + test('takes breadcrumbs from event if scope sync is disabled', () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = false; + + final eventBreadcrumb = Breadcrumb(message: 'event'); + var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); + + when(fixture.binding.loadContexts()).thenAnswer((_) async => { + 'breadcrumbs': [Breadcrumb(message: 'native').toJson()] + }); + + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; + + expect(event.breadcrumbs!.length, 1); + expect(event.breadcrumbs!.first.message, 'event'); + }); + + test('applies beforeBreadcrumb to native breadcrumbs', () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + fixture.options.beforeBreadcrumb = (breadcrumb, hint) { + if (breadcrumb?.message == 'native-mutated') { + breadcrumb?.message = 'native-mutated-applied'; + return breadcrumb; + } else { + return null; + } + }; + + final eventBreadcrumb = Breadcrumb(message: 'event'); + var event = SentryEvent(breadcrumbs: [eventBreadcrumb]); + + when(fixture.binding.loadContexts()).thenAnswer((_) async => { + 'breadcrumbs': [ + Breadcrumb(message: 'native-mutated').toJson(), + Breadcrumb(message: 'native-deleted').toJson(), + ] + }); + + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; + + expect(event.breadcrumbs!.length, 1); + expect(event.breadcrumbs!.first.message, 'native-mutated-applied'); + }); + }); - final options = fixture.options; + group('tags', () { + test('adds origin and environment tags if tags is null', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final eventSdk = getSdkVersion(name: 'sentry.dart.flutter'); + final e = getEvent(sdk: eventSdk); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.tags?['event.origin'], 'flutter'); + expect(event?.tags?['event.environment'], 'dart'); + }); + + test('merges origin and environment tags', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final eventSdk = getSdkVersion(name: 'sentry.dart.flutter'); + final e = getEvent(sdk: eventSdk, tags: {'a': 'b'}); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.tags?['event.origin'], 'flutter'); + expect(event?.tags?['event.environment'], 'dart'); + expect(event?.tags?['a'], 'b'); + }); + + test('does not add origin and environment tags if not flutter sdk', + () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(tags: {}); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.tags?.containsKey('event.origin'), false); + expect(event?.tags?.containsKey('event.environment'), false); + }); + + test('merges tags from native without overriding flutter keys', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(tags: {'key': 'flutter', 'key-a': 'flutter'}); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.tags?['key'], 'flutter'); + expect(event?.tags?['key-a'], 'flutter'); + expect(event?.tags?['key-b'], 'native'); + }); + }); - final user = SentryUser(id: expectedId); - when(fixture.binding.loadContexts()) - .thenAnswer((_) async => {'user': user.toJson()}); + group('extra', () { + test('merges extra from native without overriding flutter keys', + () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(extra: {'key': 'flutter', 'key-a': 'flutter'}); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + // ignore: deprecated_member_use + expect(event?.extra?['key'], 'flutter'); + // ignore: deprecated_member_use + expect(event?.extra?['key-a'], 'flutter'); + // ignore: deprecated_member_use + expect(event?.extra?['key-b'], 'native'); + }); + }); - final client = SentryClient(options); - final event = SentryEvent(); + group('user', () { + test('sets user from native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.user?.id, '196E065A-AAF7-409A-9A6C-A81F40274CB9'); + expect(event?.user?.username, 'fixture-username'); + expect(event?.user?.email, 'fixture-email'); + expect(event?.user?.ipAddress, 'fixture-ip_address'); + expect(event?.user?.data?['key'], 'value'); + }); + + test('does not override user with native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(user: SentryUser(id: 'abc')); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.user?.id, 'abc'); + }); + + test( + 'applies default IP to user during captureEvent if ip is null and sendDefaultPii is true', + () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + fixture.options.sendDefaultPii = true; + + const expectedIp = '{{auto}}'; + String? actualIp; + const expectedId = '1'; + String? actualId; + + fixture.options.beforeSend = (event, hint) { + actualIp = event.user?.ipAddress; + actualId = event.user?.id; + return event; + }; + + final user = SentryUser(id: expectedId); + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => {'user': user.toJson()}); + + final client = SentryClient(fixture.options); + final event = SentryEvent(); + + await client.captureEvent(event); + + expect(actualIp, expectedIp); + expect(actualId, expectedId); + }); + + test( + 'does not apply default IP to user during captureEvent if ip is null and sendDefaultPii is false', + () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + + String? actualIp; + const expectedId = '1'; + String? actualId; + + fixture.options.beforeSend = (event, hint) { + actualIp = event.user?.ipAddress; + actualId = event.user?.id; + return event; + }; + + final user = SentryUser(id: expectedId); + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => {'user': user.toJson()}); + + final client = SentryClient(fixture.options); + final event = SentryEvent(); + + await client.captureEvent(event); + + expect(actualIp, isNull); + expect(actualId, expectedId); + }); + + test( + 'applies default IP to user during captureTransaction if ip is null and sendDefaultPii is true', + () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + fixture.options.sendDefaultPii = true; + + const expectedIp = '{{auto}}'; + String? actualIp; + const expectedId = '1'; + String? actualId; + + fixture.options.beforeSendTransaction = (transaction, hint) { + actualIp = transaction.user?.ipAddress; + actualId = transaction.user?.id; + return transaction; + }; + + final user = SentryUser(id: expectedId); + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => {'user': user.toJson()}); + + final client = SentryClient(fixture.options); + final tracer = + SentryTracer(SentryTransactionContext('name', 'op'), fixture.hub); + final transaction = SentryTransaction(tracer); + + await client.captureTransaction(transaction); + + expect(actualIp, expectedIp); + expect(actualId, expectedId); + }); + + test( + 'does not apply default IP to user during captureTransaction if ip is null and sendDefaultPii is false', + () async { + await fixture.registerIntegration(); + fixture.options.enableScopeSync = true; + + String? actualIp; + const expectedId = '1'; + String? actualId; + + fixture.options.beforeSendTransaction = (transaction, hint) { + actualIp = transaction.user?.ipAddress; + actualId = transaction.user?.id; + return transaction; + }; + + final user = SentryUser(id: expectedId); + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => {'user': user.toJson()}); + + final client = SentryClient(fixture.options); + final tracer = + SentryTracer(SentryTransactionContext('name', 'op'), fixture.hub); + final transaction = SentryTransaction(tracer); + + await client.captureTransaction(transaction); + + expect(actualIp, isNull); + expect(actualId, expectedId); + }); + }); - await client.captureEvent(event); + group('dist', () { + test('sets dist from native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - expect(actualIp, isNull); - expect(actualId, expectedId); - }); + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - test( - 'apply default IP to user during captureTransaction after loading context if ip is null and sendDefaultPii is true', - () async { - await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - fixture.options.sendDefaultPii = true; + expect(event?.dist, 'fixture-dist'); + }); - const expectedIp = '{{auto}}'; - String? actualIp; + test('does not override dist with native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - const expectedId = '1'; - String? actualId; + final e = getEvent(dist: 'abc'); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - fixture.options.beforeSendTransaction = (transaction, hint) { - actualIp = transaction.user?.ipAddress; - actualId = transaction.user?.id; - return transaction; - }; + expect(event?.dist, 'abc'); + }); + }); - final options = fixture.options; + group('environment', () { + test('sets environment from native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - final user = SentryUser(id: expectedId); - when(fixture.binding.loadContexts()) - .thenAnswer((_) async => {'user': user.toJson()}); + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - final client = SentryClient(options); - final tracer = - SentryTracer(SentryTransactionContext('name', 'op'), fixture.hub); - final transaction = SentryTransaction(tracer); + expect(event?.environment, 'fixture-environment'); + }); - // ignore: invalid_use_of_internal_member - await client.captureTransaction(transaction); + test('does not override environment with native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - expect(actualIp, expectedIp); - expect(actualId, expectedId); + final e = getEvent(environment: 'abc'); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.environment, 'abc'); + }); }); - test( - 'does not apply default IP to user during captureTransaction after loading context if ip is null and sendDefaultPii is false', - () async { - await fixture.registerIntegration(); - fixture.options.enableScopeSync = true; - // sendDefaultPii false is by default + group('fingerprint', () { + test('merges fingerprint from native without duplicating entries', + () async { + mockLoadContexts(); + await fixture.registerIntegration(); - String? actualIp; + final e = getEvent(fingerprint: ['fingerprint-a', 'fingerprint-b']); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - const expectedId = '1'; - String? actualId; + expect(event?.fingerprint, ['fingerprint-a', 'fingerprint-b']); + }); + }); - fixture.options.beforeSendTransaction = (transaction, hint) { - actualIp = transaction.user?.ipAddress; - actualId = transaction.user?.id; - return transaction; - }; + group('level', () { + test('sets level from native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - final options = fixture.options; + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - final user = SentryUser(id: expectedId); - when(fixture.binding.loadContexts()) - .thenAnswer((_) async => {'user': user.toJson()}); + expect(event?.level, SentryLevel.error); + }); - final client = SentryClient(options); - final tracer = - SentryTracer(SentryTransactionContext('name', 'op'), fixture.hub); - final transaction = SentryTransaction(tracer); + test('does not override level with native', () async { + mockLoadContexts(); + await fixture.registerIntegration(); - // ignore: invalid_use_of_internal_member - await client.captureTransaction(transaction); + final e = getEvent(level: SentryLevel.fatal); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); - expect(actualIp, isNull); - expect(actualId, expectedId); + expect(event?.level, SentryLevel.fatal); + }); }); - test('add os and device attributes to log', () async { - fixture.options.enableLogs = true; + group('logs', () { + test('adds os and device attributes to log', () async { + fixture.options.enableLogs = true; + await fixture.registerIntegration(); - await fixture.registerIntegration(); + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => defaultContexts); - when(fixture.binding.loadContexts()).thenAnswer((_) async => infosJson); + final log = givenLog(); + await fixture.hub.captureLog(log); - final log = givenLog(); - await fixture.hub.captureLog(log); + expect(log.attributes['os.name']?.value, 'fixture-os-name'); + expect(log.attributes['os.version']?.value, 'fixture-os-version'); + expect(log.attributes['device.brand']?.value, 'fixture-device-brand'); + expect(log.attributes['device.model']?.value, 'fixture-device-model'); + expect(log.attributes['device.family']?.value, 'fixture-device-family'); + }); - expect(log.attributes['os.name']?.value, 'fixture-os-name'); - expect(log.attributes['os.version']?.value, 'fixture-os-version'); - expect(log.attributes['device.brand']?.value, 'fixture-device-brand'); - expect(log.attributes['device.model']?.value, 'fixture-device-model'); - expect(log.attributes['device.family']?.value, 'fixture-device-family'); - }); - - test('removes logsEnricherIntegration', () async { - final integration = LogsEnricherIntegration(); - fixture.options.addIntegration(integration); + test('removes logsEnricherIntegration', () async { + final integration = LogsEnricherIntegration(); + fixture.options.addIntegration(integration); - fixture.options.enableLogs = true; - await fixture.registerIntegration(); + fixture.options.enableLogs = true; + await fixture.registerIntegration(); - expect( + expect( fixture.options.integrations - // ignore: invalid_use_of_internal_member .any((element) => element is LogsEnricherIntegration), - isFalse); + isFalse, + ); + }); + + test( + 'does not add os and device attributes to log if enableLogs is false', + () async { + fixture.options.enableLogs = false; + await fixture.registerIntegration(); + + when(fixture.binding.loadContexts()) + .thenAnswer((_) async => defaultContexts); + + final log = givenLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes['os.name'], isNull); + expect(log.attributes['os.version'], isNull); + expect(log.attributes['device.brand'], isNull); + expect(log.attributes['device.model'], isNull); + expect(log.attributes['device.family'], isNull); + }); + + test('handles throw during loadContexts', () async { + fixture.options.enableLogs = true; + await fixture.registerIntegration(); + + when(fixture.binding.loadContexts()).thenThrow(Exception('test')); + + final log = givenLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes['os.name'], isNull); + expect(log.attributes['os.version'], isNull); + expect(log.attributes['device.brand'], isNull); + expect(log.attributes['device.model'], isNull); + expect(log.attributes['device.family'], isNull); + }); + + test('handles throw during loadContexts', () async { + fixture.options.enableLogs = true; + await fixture.registerIntegration(); + + when(fixture.binding.loadContexts()).thenThrow(Exception('test')); + + final log = givenLog(); + await fixture.hub.captureLog(log); + + // os.name and os.version are set by defaultAttributes() from Dart-level + // OS detection, not from native loadContexts(), so we only check device.* + expect(log.attributes['device.brand'], isNull); + expect(log.attributes['device.model'], isNull); + expect(log.attributes['device.family'], isNull); + }); }); - test('does not add os and device attributes to log if enableLogs is false', - () async { - fixture.options.enableLogs = false; - await fixture.registerIntegration(); - - when(fixture.binding.loadContexts()).thenAnswer((_) async => infosJson); - - final log = givenLog(); - await fixture.hub.captureLog(log); - - expect(log.attributes['os.name'], isNull); - expect(log.attributes['os.version'], isNull); - expect(log.attributes['device.brand'], isNull); - expect(log.attributes['device.model'], isNull); - expect(log.attributes['device.family'], isNull); + group('metrics', () { + test('adds native attributes to metric when metrics enabled', () async { + fixture.options.enableMetrics = true; + mockLoadContexts(); + await fixture.registerIntegration(); + + expect(fixture.options.lifecycleRegistry.lifecycleCallbacks.length, 1); + + final metric = SentryCounterMetric( + timestamp: DateTime.now(), + name: 'random', + value: 1, + traceId: SentryId.newId(), + ); + + await fixture.options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + verify(fixture.binding.loadContexts()).called(1); + final attributes = metric.attributes; + expect(attributes[SemanticAttributesConstants.osName]?.value, + 'fixture-os-name'); + expect(attributes[SemanticAttributesConstants.osVersion]?.value, + 'fixture-os-version'); + expect(attributes[SemanticAttributesConstants.deviceBrand]?.value, + 'fixture-device-brand'); + expect(attributes[SemanticAttributesConstants.deviceModel]?.value, + 'fixture-device-model'); + expect(attributes[SemanticAttributesConstants.deviceFamily]?.value, + 'fixture-device-family'); + }); + + test('does not register callback when metrics disabled', () async { + fixture.options.enableMetrics = false; + await fixture.registerIntegration(); + + expect(fixture.options.lifecycleRegistry.lifecycleCallbacks.length, 0); + }); }); - test('handles throw during loadContexts', () async { - fixture.options.enableLogs = true; - await fixture.registerIntegration(); - - when(fixture.binding.loadContexts()).thenThrow(Exception('test')); - - final log = givenLog(); - await fixture.hub.captureLog(log); - - expect(log.attributes['os.name'], isNull); - expect(log.attributes['os.version'], isNull); - expect(log.attributes['device.brand'], isNull); - expect(log.attributes['device.model'], isNull); - expect(log.attributes['device.family'], isNull); + group('close', () { + test('removes metric callback from lifecycle registry', () async { + fixture.options.enableMetrics = true; + mockLoadContexts(); + await fixture.registerIntegration(); + + expect(fixture.options.lifecycleRegistry.lifecycleCallbacks.length, 1); + + fixture.sut.close(); + + expect( + fixture.options.lifecycleRegistry.lifecycleCallbacks[OnProcessMetric], + isEmpty, + ); + }); + + test('removes log callback from lifecycle registry', () async { + fixture.options.enableLogs = true; + await fixture.registerIntegration(); + + expect( + fixture + .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + isNotEmpty, + ); + + fixture.sut.close(); + + expect( + fixture + .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + isEmpty, + ); + }); + + test('removes both callbacks when both features enabled', () async { + fixture.options.enableMetrics = true; + fixture.options.enableLogs = true; + mockLoadContexts(); + await fixture.registerIntegration(); + + expect(fixture.options.lifecycleRegistry.lifecycleCallbacks.length, 2); + + fixture.sut.close(); + + expect( + fixture.options.lifecycleRegistry.lifecycleCallbacks[OnProcessMetric], + isEmpty, + ); + expect( + fixture + .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + isEmpty, + ); + }); + + test('callback is not invoked after close', () async { + fixture.options.enableMetrics = true; + mockLoadContexts(); + await fixture.registerIntegration(); + + fixture.sut.close(); + + final metric = SentryCounterMetric( + timestamp: DateTime.now(), + name: 'random', + value: 1, + traceId: SentryId.newId(), + ); + + await fixture.options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + verifyNever(fixture.binding.loadContexts()); + expect(metric.attributes, isEmpty); + }); }); }); } diff --git a/packages/flutter/test/integrations/load_contexts_integrations_test.dart b/packages/flutter/test/integrations/load_contexts_integrations_test.dart deleted file mode 100644 index 4022d7e8cf..0000000000 --- a/packages/flutter/test/integrations/load_contexts_integrations_test.dart +++ /dev/null @@ -1,468 +0,0 @@ -@TestOn('vm') -library; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:sentry_flutter/src/integrations/load_contexts_integration.dart'; - -import '../mocks.dart'; -import '../mocks.mocks.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - SdkVersion getSdkVersion({ - String name = 'sentry.dart', - List integrations = const [], - List packages = const [], - }) { - return SdkVersion( - name: name, - version: '1.0', - integrations: integrations, - packages: packages); - } - - SentryEvent getEvent({ - SdkVersion? sdk, - Map? tags, - Map? extra, - SentryUser? user, - String? dist, - String? environment, - List? fingerprint, - SentryLevel? level, - List? breadcrumbs, - List integrations = const ['EventIntegration'], - List packages = const [], - }) { - if (packages.isEmpty) { - packages = [SentryPackage('event-package', '2.0')]; - } - return SentryEvent( - sdk: sdk ?? - getSdkVersion( - integrations: integrations, - packages: packages, - ), - tags: tags, - // ignore: deprecated_member_use - extra: extra, - user: user, - dist: dist, - environment: environment, - fingerprint: fingerprint, - level: level, - breadcrumbs: breadcrumbs, - ); - } - - test('$LoadContextsIntegration adds itself to sdk.integrations', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - expect( - fixture.options.sdk.integrations.contains('loadContextsIntegration'), - true, - ); - }); - - test('should apply the loadContextsIntegration eventProcessor', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - expect(fixture.options.eventProcessors.length, 1); - - final e = SentryEvent(); - e.contexts.operatingSystem = SentryOperatingSystem(theme: 'theme1'); - e.contexts.app = SentryApp(inForeground: true); - - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - verify(fixture.binding.loadContexts()).called(1); - expect(event?.contexts.device?.name, 'Device1'); - expect(event?.contexts.app?.name, 'test-app'); - expect(event?.contexts.app?.inForeground, true); - expect(event?.contexts.operatingSystem?.name, 'os1'); - expect(event?.contexts.operatingSystem?.theme, 'theme1'); - expect(event?.contexts.gpu?.name, 'gpu1'); - expect(event?.contexts.browser?.name, 'browser1'); - expect( - event?.contexts.runtimes.any((element) => element.name == 'RT1'), true); - expect(event?.contexts['theme'], 'material'); - expect( - event?.sdk?.packages.any((element) => element.name == 'native-package'), - true, - ); - expect(event?.sdk?.integrations.contains('NativeIntegration'), true); - expect(event?.user?.id, '196E065A-AAF7-409A-9A6C-A81F40274CB9'); - }); - - test( - 'should not override event contexts with the loadContextsIntegration infos', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - expect(fixture.options.eventProcessors.length, 1); - - final eventContexts = Contexts( - device: SentryDevice(name: 'eDevice'), - app: SentryApp(name: 'eApp', inForeground: true), - operatingSystem: SentryOperatingSystem(name: 'eOS'), - gpu: SentryGpu(name: 'eGpu'), - browser: SentryBrowser(name: 'eBrowser'), - runtimes: [SentryRuntime(name: 'eRT')]) - ..['theme'] = 'cuppertino'; - final e = - SentryEvent(contexts: eventContexts, user: SentryUser(id: 'myId')); - - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - verify(fixture.binding.loadContexts()).called(1); - expect(event?.contexts.device?.name, 'eDevice'); - expect(event?.contexts.app?.name, 'eApp'); - expect(event?.contexts.app?.inForeground, true); - expect(event?.contexts.operatingSystem?.name, 'eOS'); - expect(event?.contexts.gpu?.name, 'eGpu'); - expect(event?.contexts.browser?.name, 'eBrowser'); - expect( - event?.contexts.runtimes.any((element) => element.name == 'RT1'), true); - expect( - event?.contexts.runtimes.any((element) => element.name == 'eRT'), true); - expect(event?.contexts['theme'], 'cuppertino'); - expect(event?.user?.id, 'myId'); - }); - - test( - 'should merge event and loadContextsIntegration sdk packages and integration', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect( - event?.sdk?.packages.any((element) => element.name == 'native-package'), - true, - ); - expect( - event?.sdk?.packages.any((element) => element.name == 'event-package'), - true, - ); - expect(event?.sdk?.integrations.contains('NativeIntegration'), true); - expect(event?.sdk?.integrations.contains('EventIntegration'), true); - }, - ); - - test( - 'should not duplicate integration if already there', - () async { - final integration = fixture.getSut(contexts: { - 'integrations': ['EventIntegration'] - }); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect( - event?.sdk?.integrations - .where((element) => element == 'EventIntegration') - .toList(growable: false) - .length, - 1); - }, - ); - - test( - 'should not duplicate package if already there', - () async { - final integration = fixture.getSut(contexts: { - 'package': {'sdk_name': 'event-package', 'version': '2.0'} - }); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect( - event?.sdk?.packages - .where((element) => - element.name == 'event-package' && element.version == '2.0') - .toList(growable: false) - .length, - 1); - }, - ); - - test( - 'adds package if different version', - () async { - final integration = fixture.getSut(contexts: { - 'package': {'sdk_name': 'event-package', 'version': '3.0'} - }); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect( - event?.sdk?.packages - .where((element) => - element.name == 'event-package' && element.version == '2.0') - .toList(growable: false) - .length, - 1); - - expect( - event?.sdk?.packages - .where((element) => - element.name == 'event-package' && element.version == '3.0') - .toList(growable: false) - .length, - 1); - }, - ); - - test('should not throw on loadContextsIntegration exception', () async { - when(fixture.binding.loadContexts()).thenThrow(Exception()); - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = SentryEvent(); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event, isNotNull); - }); - - test( - 'should add origin and environment tags if tags is null', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final eventSdk = getSdkVersion(name: 'sentry.dart.flutter'); - final e = getEvent(sdk: eventSdk); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.tags?['event.origin'], 'flutter'); - expect(event?.tags?['event.environment'], 'dart'); - }, - ); - - test( - 'should merge origin and environment tags', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final eventSdk = getSdkVersion(name: 'sentry.dart.flutter'); - final e = getEvent( - sdk: eventSdk, - tags: {'a': 'b'}, - ); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.tags?['event.origin'], 'flutter'); - expect(event?.tags?['event.environment'], 'dart'); - expect(event?.tags?['a'], 'b'); - }, - ); - - test( - 'should not add origin and environment tags if not flutter sdk', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(tags: {}); - final event = - await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.tags?.containsKey('event.origin'), false); - expect(event?.tags?.containsKey('event.environment'), false); - }, - ); - - test('should merge in tags from native without overriding flutter keys', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(tags: {'key': 'flutter', 'key-a': 'flutter'}); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.tags?['key'], 'flutter'); - expect(event?.tags?['key-a'], 'flutter'); - expect(event?.tags?['key-b'], 'native'); - }); - - test('should merge in extra from native without overriding flutter keys', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(extra: {'key': 'flutter', 'key-a': 'flutter'}); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - // ignore: deprecated_member_use - expect(event?.extra?['key'], 'flutter'); - // ignore: deprecated_member_use - expect(event?.extra?['key-a'], 'flutter'); - // ignore: deprecated_member_use - expect(event?.extra?['key-b'], 'native'); - }); - - test('should set user from native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.user?.id, '196E065A-AAF7-409A-9A6C-A81F40274CB9'); - expect(event?.user?.username, 'fixture-username'); - expect(event?.user?.email, 'fixture-email'); - expect(event?.user?.ipAddress, 'fixture-ip_address'); - expect(event?.user?.data?['key'], 'value'); - }); - - test('should not override user with native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(user: SentryUser(id: 'abc')); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.user?.id, 'abc'); - }); - - test('should set dist from native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.dist, 'fixture-dist'); - }); - - test('should not override dist with native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(dist: 'abc'); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.dist, 'abc'); - }); - - test('should set environment from native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.environment, 'fixture-environment'); - }); - - test('should not override environment with native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(environment: 'abc'); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.environment, 'abc'); - }); - - test('should merge in fingerprint from native without duplicating entries', - () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(fingerprint: ['fingerprint-a', 'fingerprint-b']); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.fingerprint, ['fingerprint-a', 'fingerprint-b']); - }); - - test('should set level from native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.level, SentryLevel.error); - }); - - test('should not override level with native', () async { - final integration = fixture.getSut(); - integration(fixture.hub, fixture.options); - - final e = getEvent(level: SentryLevel.fatal); - final event = await fixture.options.eventProcessors.first.apply(e, Hint()); - - expect(event?.level, SentryLevel.fatal); - }); -} - -class Fixture { - final hub = MockHub(); - final options = defaultTestOptions(); - final binding = MockSentryNativeBinding(); - - LoadContextsIntegration getSut( - {Map contexts = const { - 'integrations': ['NativeIntegration'], - 'package': {'sdk_name': 'native-package', 'version': '1.0'}, - 'contexts': { - 'device': {'name': 'Device1'}, - 'app': {'app_name': 'test-app'}, - 'os': {'name': 'os1'}, - 'gpu': {'name': 'gpu1'}, - 'browser': {'name': 'browser1'}, - 'runtime': {'name': 'RT1'}, - 'theme': 'material', - }, - 'user': { - 'id': '196E065A-AAF7-409A-9A6C-A81F40274CB9', - 'username': 'fixture-username', - 'email': 'fixture-email', - 'ip_address': 'fixture-ip_address', - 'data': {'key': 'value'}, - }, - 'tags': {'key-a': 'native', 'key-b': 'native'}, - 'extra': {'key-a': 'native', 'key-b': 'native'}, - 'dist': 'fixture-dist', - 'environment': 'fixture-environment', - 'fingerprint': ['fingerprint-a'], - 'level': 'error', - 'breadcrumbs': [ - { - 'timestamp': '1970-01-01T00:00:00.000Z', - 'message': 'native-crumb', - } - ] - }}) { - when(binding.loadContexts()).thenAnswer((_) async => contexts); - return LoadContextsIntegration(binding); - } -} diff --git a/packages/flutter/test/integrations/replay_log_integration_test.dart b/packages/flutter/test/integrations/replay_log_integration_test.dart deleted file mode 100644 index 7a667a050e..0000000000 --- a/packages/flutter/test/integrations/replay_log_integration_test.dart +++ /dev/null @@ -1,303 +0,0 @@ -// ignore_for_file: invalid_use_of_internal_member - -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:sentry_flutter/src/integrations/replay_log_integration.dart'; - -import '../mocks.mocks.dart'; - -void main() { - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - group('ReplayLogIntegration', () { - test('does not register when replay is disabled', () async { - final integration = fixture.getSut(); - fixture.options.replay.sessionSampleRate = 0.0; - fixture.options.replay.onErrorSampleRate = 0.0; - - await integration.call(fixture.hub, fixture.options); - - // Integration should not be registered when replay is disabled - expect(fixture.options.sdk.integrations.contains('ReplayLog'), false); - }); - - test( - 'adds replay_id attribute when sessionSampleRate > 0 and scope replayId is set', - () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = 0.5; - fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - expect(log.attributes['sentry.replay_id']?.value, 'testreplayid'); - expect(log.attributes['sentry.replay_id']?.type, 'string'); - - // When scope replayId is set via session sample rate, no buffering flag should be added - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'does not add replay_id when sessionSampleRate is 0 even if scope replayId is set', - () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = 0.0; - fixture.options.replay.onErrorSampleRate = 0.5; // Needed to enable replay - fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // With sessionSampleRate = 0, scope replay ID should not be used - // (even though it's set, we're not in session mode) - expect(log.attributes.containsKey('sentry.replay_id'), false); - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'does not add replay_id when sessionSampleRate is null even if scope replayId is set', - () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = null; - fixture.options.replay.onErrorSampleRate = 0.5; // Needed to enable replay - fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // With sessionSampleRate = null (treated as 0), scope replay ID should not be used - expect(log.attributes.containsKey('sentry.replay_id'), false); - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'uses replay_id when set on scope and sessionSampleRate > 0 (active session mode)', - () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = 0.5; - fixture.options.replay.onErrorSampleRate = 0.5; - final replayId = SentryId.fromId('test-replay-id'); - fixture.hub.scope.replayId = replayId; - - // Mock native replayId with the same value (same replay, just also set on scope) - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // Should use the replay ID from scope (active session mode) - expect(log.attributes['sentry.replay_id']?.value, 'testreplayid'); - expect(log.attributes['sentry.replay_id']?.type, 'string'); - - // Should NOT add buffering flag when replay is active on scope - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'adds replay_id and buffering flag when replay is in buffer mode (scope null, native has ID)', - () async { - final integration = fixture.getSut(); - fixture.options.replay.onErrorSampleRate = 0.5; - // Scope replay ID is null (default), so we're in buffer mode - - // Mock native replayId to simulate buffering mode (same replay, not on scope yet) - final replayId = SentryId.fromId('test-replay-id'); - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // In buffering mode, use native replay ID and add buffering flag - expect(log.attributes['sentry.replay_id']?.value, 'testreplayid'); - expect(log.attributes['sentry.replay_id']?.type, 'string'); - - expect( - log.attributes['sentry._internal.replay_is_buffering']?.value, true); - expect(log.attributes['sentry._internal.replay_is_buffering']?.type, - 'boolean'); - }); - - test( - 'does not add anything when onErrorSampleRate is 0 and no scope replayId', - () async { - final integration = fixture.getSut(); - fixture.options.replay.sessionSampleRate = 0.5; // Needed to enable replay - fixture.options.replay.onErrorSampleRate = 0.0; - // Scope replay ID is null (default) - - // Mock native replayId to simulate what would be buffering mode - final replayId = SentryId.fromId('test-replay-id'); - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // When onErrorSampleRate is 0, native replayId should be ignored even if it exists - expect(log.attributes.containsKey('sentry.replay_id'), false); - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'does not add anything when onErrorSampleRate is null and no scope replayId', - () async { - final integration = fixture.getSut(); - fixture.options.replay.sessionSampleRate = 0.5; // Needed to enable replay - fixture.options.replay.onErrorSampleRate = null; - // Scope replay ID is null (default) - - // Mock native replayId to simulate what would be buffering mode - final replayId = SentryId.fromId('test-replay-id'); - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // When onErrorSampleRate is null (treated as 0), native replayId should be ignored - expect(log.attributes.containsKey('sentry.replay_id'), false); - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test( - 'adds replay_id when scope is null but native has ID and onErrorSampleRate > 0 (buffer mode)', - () async { - final integration = fixture.getSut(); - fixture.options.replay.sessionSampleRate = 0.0; - fixture.options.replay.onErrorSampleRate = 0.5; - // Scope replay ID is null (default), so we're in buffer mode - - // Mock native replayId to simulate buffering mode (replay exists but not on scope) - final replayId = SentryId.fromId('test-replay-id'); - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - // When scope is null but native has replay ID, use it in buffer mode - expect(log.attributes['sentry.replay_id']?.value, 'testreplayid'); - expect(log.attributes['sentry.replay_id']?.type, 'string'); - expect( - log.attributes['sentry._internal.replay_is_buffering']?.value, true); - expect(log.attributes['sentry._internal.replay_is_buffering']?.type, - 'boolean'); - }); - - test('registers integration name in SDK with sessionSampleRate', () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = 0.5; - fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); - - await integration.call(fixture.hub, fixture.options); - - // Integration name is registered in SDK - expect(fixture.options.sdk.integrations.contains('ReplayLog'), true); - }); - - test('registers integration name in SDK with onErrorSampleRate', () async { - final integration = fixture.getSut(); - - fixture.options.replay.onErrorSampleRate = 0.5; - - // Mock native replayId - final replayId = SentryId.fromId('test-replay-id'); - when(fixture.nativeBinding.replayId).thenReturn(replayId); - - await integration.call(fixture.hub, fixture.options); - - // Integration name is registered in SDK - expect(fixture.options.sdk.integrations.contains('ReplayLog'), true); - }); - - test('removes callback on close', () async { - final integration = fixture.getSut(); - - fixture.options.replay.sessionSampleRate = 0.5; - fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); - - await integration.call(fixture.hub, fixture.options); - await integration.close(); - - final log = fixture.createTestLog(); - await fixture.hub.captureLog(log); - - expect(log.attributes.containsKey('sentry.replay_id'), false); - expect(log.attributes.containsKey('sentry._internal.replay_is_buffering'), - false); - }); - - test('integration name is correct', () { - expect(ReplayLogIntegration.integrationName, 'ReplayLog'); - }); - }); -} - -class Fixture { - final options = - SentryFlutterOptions(dsn: 'https://abc@def.ingest.sentry.io/1234567'); - final hub = MockHub(); - final nativeBinding = MockSentryNativeBinding(); - - Fixture() { - options.enableLogs = true; - options.environment = 'test'; - options.release = 'test-release'; - - final scope = Scope(options); - when(hub.options).thenReturn(options); - when(hub.scope).thenReturn(scope); - when(hub.captureLog(any)).thenAnswer((invocation) async { - final log = invocation.positionalArguments.first as SentryLog; - // Trigger the lifecycle callback - await options.lifecycleRegistry.dispatchCallback(OnBeforeCaptureLog(log)); - }); - - // Default: no native replayId - when(nativeBinding.replayId).thenReturn(null); - } - - SentryLog createTestLog() { - return SentryLog( - timestamp: DateTime.now(), - traceId: SentryId.newId(), - level: SentryLogLevel.info, - body: 'test log message', - attributes: {}, - ); - } - - ReplayLogIntegration getSut() { - return ReplayLogIntegration(nativeBinding); - } -} diff --git a/packages/flutter/test/integrations/replay_telemetry_integration_test.dart b/packages/flutter/test/integrations/replay_telemetry_integration_test.dart new file mode 100644 index 0000000000..460c0c0c0a --- /dev/null +++ b/packages/flutter/test/integrations/replay_telemetry_integration_test.dart @@ -0,0 +1,220 @@ +// ignore_for_file: invalid_use_of_internal_member + +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_flutter/src/integrations/replay_telemetry_integration.dart'; + +import '../mocks.mocks.dart'; + +const _replayId = SemanticAttributesConstants.sentryReplayId; +const _replayIsBuffering = + SemanticAttributesConstants.sentryInternalReplayIsBuffering; + +void main() { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('$ReplayTelemetryIntegration', () { + group('when replay is disabled', () { + test('does not register', () async { + fixture.options.replay.sessionSampleRate = 0.0; + fixture.options.replay.onErrorSampleRate = 0.0; + + await fixture.getSut().call(fixture.hub, fixture.options); + + expect(fixture.options.sdk.integrations, + isNot(contains('ReplayTelemetry'))); + }); + }); + + group('when replay is enabled', () { + test('registers integration', () async { + fixture.options.replay.sessionSampleRate = 0.5; + + await fixture.getSut().call(fixture.hub, fixture.options); + + expect(fixture.options.sdk.integrations, contains('ReplayTelemetry')); + }); + }); + + group('in session mode', () { + setUp(() { + fixture.options.replay.sessionSampleRate = 0.5; + fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); + }); + + test('adds replay_id to logs', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes[_replayId]?.value, 'testreplayid'); + }); + + test('adds replay_id to metrics', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final metric = fixture.createTestMetric(); + await fixture.options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + expect(metric.attributes[_replayId]?.value, 'testreplayid'); + }); + + test('does not add buffering flag', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes.containsKey(_replayIsBuffering), false); + }); + }); + + group('in buffer mode', () { + setUp(() { + fixture.options.replay.onErrorSampleRate = 0.5; + when(fixture.nativeBinding.replayId) + .thenReturn(SentryId.fromId('test-replay-id')); + }); + + test('adds replay_id to logs', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes[_replayId]?.value, 'testreplayid'); + }); + + test('adds replay_id to metrics', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final metric = fixture.createTestMetric(); + await fixture.options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + expect(metric.attributes[_replayId]?.value, 'testreplayid'); + }); + + test('adds buffering flag', () async { + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes[_replayIsBuffering]?.value, true); + }); + }); + + group('with zero or null sample rates', () { + for (final rate in [0.0, null]) { + test('ignores scope replayId when sessionSampleRate is $rate', + () async { + fixture.options.replay.sessionSampleRate = rate; + fixture.options.replay.onErrorSampleRate = 0.5; + fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); + + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes.containsKey(_replayId), false); + }); + + test('ignores native replayId when onErrorSampleRate is $rate', + () async { + fixture.options.replay.sessionSampleRate = 0.5; + fixture.options.replay.onErrorSampleRate = rate; + when(fixture.nativeBinding.replayId) + .thenReturn(SentryId.fromId('test-replay-id')); + + await fixture.getSut().call(fixture.hub, fixture.options); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes.containsKey(_replayId), false); + }); + } + }); + + group('when closed', () { + test('removes log callback', () async { + fixture.options.replay.sessionSampleRate = 0.5; + fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); + + final sut = fixture.getSut(); + await sut.call(fixture.hub, fixture.options); + await sut.close(); + + final log = fixture.createTestLog(); + await fixture.hub.captureLog(log); + + expect(log.attributes.containsKey(_replayId), false); + }); + + test('removes metric callback', () async { + fixture.options.replay.sessionSampleRate = 0.5; + fixture.hub.scope.replayId = SentryId.fromId('test-replay-id'); + + final sut = fixture.getSut(); + await sut.call(fixture.hub, fixture.options); + await sut.close(); + + final metric = fixture.createTestMetric(); + await fixture.options.lifecycleRegistry + .dispatchCallback(OnProcessMetric(metric)); + + expect(metric.attributes.containsKey(_replayId), false); + }); + }); + }); +} + +class Fixture { + final options = + SentryFlutterOptions(dsn: 'https://abc@def.ingest.sentry.io/1234567'); + final hub = MockHub(); + final nativeBinding = MockSentryNativeBinding(); + + Fixture() { + options.enableLogs = true; + options.environment = 'test'; + options.release = 'test-release'; + + final scope = Scope(options); + when(hub.options).thenReturn(options); + when(hub.scope).thenReturn(scope); + when(hub.captureLog(any)).thenAnswer((invocation) async { + final log = invocation.positionalArguments.first as SentryLog; + await options.lifecycleRegistry.dispatchCallback(OnBeforeCaptureLog(log)); + }); + when(nativeBinding.replayId).thenReturn(null); + } + + SentryLog createTestLog() => SentryLog( + timestamp: DateTime.now(), + traceId: SentryId.newId(), + level: SentryLogLevel.info, + body: 'test log message', + attributes: {}, + ); + + SentryMetric createTestMetric() => SentryCounterMetric( + timestamp: DateTime.now(), + name: 'test-metric', + value: 1, + traceId: SentryId.newId(), + attributes: {}, + ); + + ReplayTelemetryIntegration getSut() => + ReplayTelemetryIntegration(nativeBinding); +} diff --git a/packages/flutter/test/mocks.dart b/packages/flutter/test/mocks.dart index af190bf78e..7c59da2b7f 100644 --- a/packages/flutter/test/mocks.dart +++ b/packages/flutter/test/mocks.dart @@ -240,6 +240,7 @@ class MockLogItem { class MockTelemetryProcessor implements TelemetryProcessor { final List addedLogs = []; + final List addedMetrics = []; int flushCalls = 0; int closeCalls = 0; @@ -248,6 +249,11 @@ class MockTelemetryProcessor implements TelemetryProcessor { addedLogs.add(log); } + @override + void addMetric(SentryMetric metric) { + addedMetrics.add(metric); + } + @override void flush() { flushCalls++; diff --git a/packages/flutter/test/mocks.mocks.dart b/packages/flutter/test/mocks.mocks.dart index 9c0fd9755a..db45428c78 100644 --- a/packages/flutter/test/mocks.mocks.dart +++ b/packages/flutter/test/mocks.mocks.dart @@ -3,37 +3,39 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i11; -import 'dart:developer' as _i21; -import 'dart:typed_data' as _i17; +import 'dart:async' as _i12; +import 'dart:developer' as _i23; +import 'dart:typed_data' as _i19; import 'dart:ui' as _i6; import 'package:flutter/foundation.dart' as _i8; import 'package:flutter/gestures.dart' as _i7; import 'package:flutter/rendering.dart' as _i10; -import 'package:flutter/scheduler.dart' as _i20; +import 'package:flutter/scheduler.dart' as _i22; import 'package:flutter/services.dart' as _i4; +import 'package:flutter/src/widgets/_window.dart' as _i11; import 'package:flutter/src/widgets/binding.dart' as _i5; import 'package:flutter/widgets.dart' as _i9; -import 'package:flutter_test/flutter_test.dart' as _i12; +import 'package:flutter_test/flutter_test.dart' as _i13; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i14; -import 'package:sentry/src/profiling.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; +import 'package:sentry/src/profiling.dart' as _i16; import 'package:sentry/src/sentry_tracer.dart' as _i3; +import 'package:sentry/src/telemetry/metric/metric.dart' as _i17; import 'package:sentry_flutter/sentry_flutter.dart' as _i2; import 'package:sentry_flutter/src/frames_tracking/sentry_delayed_frames_tracker.dart' - as _i19; -import 'package:sentry_flutter/src/native/sentry_native_binding.dart' as _i16; + as _i21; +import 'package:sentry_flutter/src/native/sentry_native_binding.dart' as _i18; import 'package:sentry_flutter/src/navigation/time_to_display_tracker.dart' - as _i23; -import 'package:sentry_flutter/src/navigation/time_to_full_display_tracker.dart' as _i25; +import 'package:sentry_flutter/src/navigation/time_to_full_display_tracker.dart' + as _i27; import 'package:sentry_flutter/src/navigation/time_to_initial_display_tracker.dart' - as _i24; -import 'package:sentry_flutter/src/replay/replay_config.dart' as _i18; -import 'package:sentry_flutter/src/web/sentry_js_binding.dart' as _i22; + as _i26; +import 'package:sentry_flutter/src/replay/replay_config.dart' as _i20; +import 'package:sentry_flutter/src/web/sentry_js_binding.dart' as _i24; -import 'mocks.dart' as _i13; +import 'mocks.dart' as _i14; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -48,6 +50,7 @@ import 'mocks.dart' as _i13; // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member class _FakeSentrySpanContext_0 extends _i1.SmartFake implements _i2.SentrySpanContext { @@ -218,8 +221,8 @@ class _FakePointerSignalResolver_15 extends _i1.SmartFake ); } -class _FakeDuration_16 extends _i1.SmartFake implements Duration { - _FakeDuration_16( +class _FakeSamplingClock_16 extends _i1.SmartFake implements _i7.SamplingClock { + _FakeSamplingClock_16( Object parent, Invocation parentInvocation, ) : super( @@ -228,8 +231,8 @@ class _FakeDuration_16 extends _i1.SmartFake implements Duration { ); } -class _FakeSamplingClock_17 extends _i1.SmartFake implements _i7.SamplingClock { - _FakeSamplingClock_17( +class _FakeDuration_17 extends _i1.SmartFake implements Duration { + _FakeDuration_17( Object parent, Invocation parentInvocation, ) : super( @@ -238,9 +241,9 @@ class _FakeSamplingClock_17 extends _i1.SmartFake implements _i7.SamplingClock { ); } -class _FakeValueNotifier_18 extends _i1.SmartFake - implements _i8.ValueNotifier { - _FakeValueNotifier_18( +class _FakeHardwareKeyboard_18 extends _i1.SmartFake + implements _i4.HardwareKeyboard { + _FakeHardwareKeyboard_18( Object parent, Invocation parentInvocation, ) : super( @@ -249,9 +252,9 @@ class _FakeValueNotifier_18 extends _i1.SmartFake ); } -class _FakeHardwareKeyboard_19 extends _i1.SmartFake - implements _i4.HardwareKeyboard { - _FakeHardwareKeyboard_19( +class _FakeKeyEventManager_19 extends _i1.SmartFake + implements _i4.KeyEventManager { + _FakeKeyEventManager_19( Object parent, Invocation parentInvocation, ) : super( @@ -260,9 +263,9 @@ class _FakeHardwareKeyboard_19 extends _i1.SmartFake ); } -class _FakeKeyEventManager_20 extends _i1.SmartFake - implements _i4.KeyEventManager { - _FakeKeyEventManager_20( +class _FakeChannelBuffers_20 extends _i1.SmartFake + implements _i6.ChannelBuffers { + _FakeChannelBuffers_20( Object parent, Invocation parentInvocation, ) : super( @@ -271,9 +274,9 @@ class _FakeKeyEventManager_20 extends _i1.SmartFake ); } -class _FakeChannelBuffers_21 extends _i1.SmartFake - implements _i6.ChannelBuffers { - _FakeChannelBuffers_21( +class _FakeValueNotifier_21 extends _i1.SmartFake + implements _i8.ValueNotifier { + _FakeValueNotifier_21( Object parent, Invocation parentInvocation, ) : super( @@ -324,8 +327,18 @@ class _FakeAccessibilityFeatures_25 extends _i1.SmartFake ); } -class _FakeRenderView_26 extends _i1.SmartFake implements _i10.RenderView { - _FakeRenderView_26( +class _FakeMouseTracker_26 extends _i1.SmartFake implements _i10.MouseTracker { + _FakeMouseTracker_26( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeRenderView_27 extends _i1.SmartFake implements _i10.RenderView { + _FakeRenderView_27( Object parent, Invocation parentInvocation, ) : super( @@ -338,19 +351,23 @@ class _FakeRenderView_26 extends _i1.SmartFake implements _i10.RenderView { super.toString(); } -class _FakeMouseTracker_27 extends _i1.SmartFake implements _i10.MouseTracker { - _FakeMouseTracker_27( +class _FakeFocusManager_28 extends _i1.SmartFake implements _i9.FocusManager { + _FakeFocusManager_28( Object parent, Invocation parentInvocation, ) : super( parent, parentInvocation, ); + + @override + String toString({_i4.DiagnosticLevel? minLevel = _i4.DiagnosticLevel.info}) => + super.toString(); } -class _FakePlatformMenuDelegate_28 extends _i1.SmartFake +class _FakePlatformMenuDelegate_29 extends _i1.SmartFake implements _i9.PlatformMenuDelegate { - _FakePlatformMenuDelegate_28( + _FakePlatformMenuDelegate_29( Object parent, Invocation parentInvocation, ) : super( @@ -359,22 +376,19 @@ class _FakePlatformMenuDelegate_28 extends _i1.SmartFake ); } -class _FakeFocusManager_29 extends _i1.SmartFake implements _i9.FocusManager { - _FakeFocusManager_29( +class _FakeWindowingOwner_30 extends _i1.SmartFake + implements _i11.WindowingOwner { + _FakeWindowingOwner_30( Object parent, Invocation parentInvocation, ) : super( parent, parentInvocation, ); - - @override - String toString({_i4.DiagnosticLevel? minLevel = _i4.DiagnosticLevel.info}) => - super.toString(); } -class _FakeFuture_30 extends _i1.SmartFake implements _i11.Future { - _FakeFuture_30( +class _FakeFuture_31 extends _i1.SmartFake implements _i12.Future { + _FakeFuture_31( Object parent, Invocation parentInvocation, ) : super( @@ -383,8 +397,8 @@ class _FakeFuture_30 extends _i1.SmartFake implements _i11.Future { ); } -class _FakeCodec_31 extends _i1.SmartFake implements _i6.Codec { - _FakeCodec_31( +class _FakeCodec_32 extends _i1.SmartFake implements _i6.Codec { + _FakeCodec_32( Object parent, Invocation parentInvocation, ) : super( @@ -393,9 +407,9 @@ class _FakeCodec_31 extends _i1.SmartFake implements _i6.Codec { ); } -class _FakeSemanticsHandle_32 extends _i1.SmartFake - implements _i12.SemanticsHandle { - _FakeSemanticsHandle_32( +class _FakeSemanticsHandle_33 extends _i1.SmartFake + implements _i13.SemanticsHandle { + _FakeSemanticsHandle_33( Object parent, Invocation parentInvocation, ) : super( @@ -404,9 +418,9 @@ class _FakeSemanticsHandle_32 extends _i1.SmartFake ); } -class _FakeSemanticsUpdateBuilder_33 extends _i1.SmartFake +class _FakeSemanticsUpdateBuilder_34 extends _i1.SmartFake implements _i6.SemanticsUpdateBuilder { - _FakeSemanticsUpdateBuilder_33( + _FakeSemanticsUpdateBuilder_34( Object parent, Invocation parentInvocation, ) : super( @@ -415,9 +429,9 @@ class _FakeSemanticsUpdateBuilder_33 extends _i1.SmartFake ); } -class _FakeViewConfiguration_34 extends _i1.SmartFake +class _FakeViewConfiguration_35 extends _i1.SmartFake implements _i10.ViewConfiguration { - _FakeViewConfiguration_34( + _FakeViewConfiguration_35( Object parent, Invocation parentInvocation, ) : super( @@ -426,8 +440,8 @@ class _FakeViewConfiguration_34 extends _i1.SmartFake ); } -class _FakeSceneBuilder_35 extends _i1.SmartFake implements _i6.SceneBuilder { - _FakeSceneBuilder_35( +class _FakeSceneBuilder_36 extends _i1.SmartFake implements _i6.SceneBuilder { + _FakeSceneBuilder_36( Object parent, Invocation parentInvocation, ) : super( @@ -436,9 +450,9 @@ class _FakeSceneBuilder_35 extends _i1.SmartFake implements _i6.SceneBuilder { ); } -class _FakePictureRecorder_36 extends _i1.SmartFake +class _FakePictureRecorder_37 extends _i1.SmartFake implements _i6.PictureRecorder { - _FakePictureRecorder_36( + _FakePictureRecorder_37( Object parent, Invocation parentInvocation, ) : super( @@ -447,8 +461,8 @@ class _FakePictureRecorder_36 extends _i1.SmartFake ); } -class _FakeCanvas_37 extends _i1.SmartFake implements _i6.Canvas { - _FakeCanvas_37( +class _FakeCanvas_38 extends _i1.SmartFake implements _i6.Canvas { + _FakeCanvas_38( Object parent, Invocation parentInvocation, ) : super( @@ -457,8 +471,8 @@ class _FakeCanvas_37 extends _i1.SmartFake implements _i6.Canvas { ); } -class _FakeWidget_38 extends _i1.SmartFake implements _i9.Widget { - _FakeWidget_38( +class _FakeWidget_39 extends _i1.SmartFake implements _i9.Widget { + _FakeWidget_39( Object parent, Invocation parentInvocation, ) : super( @@ -471,9 +485,9 @@ class _FakeWidget_38 extends _i1.SmartFake implements _i9.Widget { super.toString(); } -class _FakeSentryFlutterOptions_39 extends _i1.SmartFake +class _FakeSentryFlutterOptions_40 extends _i1.SmartFake implements _i2.SentryFlutterOptions { - _FakeSentryFlutterOptions_39( + _FakeSentryFlutterOptions_40( Object parent, Invocation parentInvocation, ) : super( @@ -482,8 +496,8 @@ class _FakeSentryFlutterOptions_39 extends _i1.SmartFake ); } -class _FakeSentryOptions_40 extends _i1.SmartFake implements _i2.SentryOptions { - _FakeSentryOptions_40( +class _FakeSentryOptions_41 extends _i1.SmartFake implements _i2.SentryOptions { + _FakeSentryOptions_41( Object parent, Invocation parentInvocation, ) : super( @@ -492,8 +506,8 @@ class _FakeSentryOptions_40 extends _i1.SmartFake implements _i2.SentryOptions { ); } -class _FakeScope_41 extends _i1.SmartFake implements _i2.Scope { - _FakeScope_41( +class _FakeScope_42 extends _i1.SmartFake implements _i2.Scope { + _FakeScope_42( Object parent, Invocation parentInvocation, ) : super( @@ -502,8 +516,8 @@ class _FakeScope_41 extends _i1.SmartFake implements _i2.Scope { ); } -class _FakeHub_42 extends _i1.SmartFake implements _i2.Hub { - _FakeHub_42( +class _FakeHub_43 extends _i1.SmartFake implements _i2.Hub { + _FakeHub_43( Object parent, Invocation parentInvocation, ) : super( @@ -515,13 +529,13 @@ class _FakeHub_42 extends _i1.SmartFake implements _i2.Hub { /// A class which mocks [Callbacks]. /// /// See the documentation for Mockito's code generation for more information. -class MockCallbacks extends _i1.Mock implements _i13.Callbacks { +class MockCallbacks extends _i1.Mock implements _i14.Callbacks { MockCallbacks() { _i1.throwOnMissingStub(this); } @override - _i11.Future? methodCallHandler( + _i12.Future? methodCallHandler( String? method, [ dynamic arguments, ]) => @@ -531,7 +545,7 @@ class MockCallbacks extends _i1.Mock implements _i13.Callbacks { method, arguments, ], - )) as _i11.Future?); + )) as _i12.Future?); } /// A class which mocks [Transport]. @@ -543,14 +557,14 @@ class MockTransport extends _i1.Mock implements _i2.Transport { } @override - _i11.Future<_i2.SentryId?> send(_i2.SentryEnvelope? envelope) => + _i12.Future<_i2.SentryId?> send(_i2.SentryEnvelope? envelope) => (super.noSuchMethod( Invocation.method( #send, [envelope], ), - returnValue: _i11.Future<_i2.SentryId?>.value(), - ) as _i11.Future<_i2.SentryId?>); + returnValue: _i12.Future<_i2.SentryId?>.value(), + ) as _i12.Future<_i2.SentryId?>); } /// A class which mocks [SentryTracer]. @@ -564,12 +578,18 @@ class MockSentryTracer extends _i1.Mock implements _i3.SentryTracer { @override String get name => (super.noSuchMethod( Invocation.getter(#name), - returnValue: _i14.dummyValue( + returnValue: _i15.dummyValue( this, Invocation.getter(#name), ), ) as String); + @override + Map get measurements => (super.noSuchMethod( + Invocation.getter(#measurements), + returnValue: {}, + ) as Map); + @override _i2.SentryTransactionNameSource get transactionNameSource => (super.noSuchMethod( @@ -577,12 +597,6 @@ class MockSentryTracer extends _i1.Mock implements _i3.SentryTracer { returnValue: _i2.SentryTransactionNameSource.custom, ) as _i2.SentryTransactionNameSource); - @override - Map get measurements => (super.noSuchMethod( - Invocation.getter(#measurements), - returnValue: {}, - ) as Map); - @override _i2.SentrySpanContext get context => (super.noSuchMethod( Invocation.getter(#context), @@ -626,39 +640,38 @@ class MockSentryTracer extends _i1.Mock implements _i3.SentryTracer { ) as Map); @override - set name(String? _name) => super.noSuchMethod( + set name(String? value) => super.noSuchMethod( Invocation.setter( #name, - _name, + value, ), returnValueForMissingStub: null, ); @override - set transactionNameSource( - _i2.SentryTransactionNameSource? _transactionNameSource) => + set transactionNameSource(_i2.SentryTransactionNameSource? value) => super.noSuchMethod( Invocation.setter( #transactionNameSource, - _transactionNameSource, + value, ), returnValueForMissingStub: null, ); @override - set profiler(_i15.SentryProfiler? _profiler) => super.noSuchMethod( + set profiler(_i16.SentryProfiler? value) => super.noSuchMethod( Invocation.setter( #profiler, - _profiler, + value, ), returnValueForMissingStub: null, ); @override - set profileInfo(_i15.SentryProfileInfo? _profileInfo) => super.noSuchMethod( + set profileInfo(_i16.SentryProfileInfo? value) => super.noSuchMethod( Invocation.setter( #profileInfo, - _profileInfo, + value, ), returnValueForMissingStub: null, ); @@ -691,7 +704,7 @@ class MockSentryTracer extends _i1.Mock implements _i3.SentryTracer { ); @override - _i11.Future finish({ + _i12.Future finish({ _i2.SpanStatus? status, DateTime? endTimestamp, _i2.Hint? hint, @@ -706,9 +719,9 @@ class MockSentryTracer extends _i1.Mock implements _i3.SentryTracer { #hint: hint, }, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void removeData(String? key) => super.noSuchMethod( @@ -935,39 +948,38 @@ class MockSentryTransaction extends _i1.Mock implements _i2.SentryTransaction { ) as bool); @override - set startTimestamp(DateTime? _startTimestamp) => super.noSuchMethod( + set startTimestamp(DateTime? value) => super.noSuchMethod( Invocation.setter( #startTimestamp, - _startTimestamp, + value, ), returnValueForMissingStub: null, ); @override - set spans(List<_i2.SentrySpan>? _spans) => super.noSuchMethod( + set spans(List<_i2.SentrySpan>? value) => super.noSuchMethod( Invocation.setter( #spans, - _spans, + value, ), returnValueForMissingStub: null, ); @override - set measurements(Map? _measurements) => + set measurements(Map? value) => super.noSuchMethod( Invocation.setter( #measurements, - _measurements, + value, ), returnValueForMissingStub: null, ); @override - set transactionInfo(_i2.SentryTransactionInfo? _transactionInfo) => - super.noSuchMethod( + set transactionInfo(_i2.SentryTransactionInfo? value) => super.noSuchMethod( Invocation.setter( #transactionInfo, - _transactionInfo, + value, ), returnValueForMissingStub: null, ); @@ -991,226 +1003,226 @@ class MockSentryTransaction extends _i1.Mock implements _i2.SentryTransaction { ) as _i2.Contexts); @override - set eventId(_i2.SentryId? _eventId) => super.noSuchMethod( + set eventId(_i2.SentryId? value) => super.noSuchMethod( Invocation.setter( #eventId, - _eventId, + value, ), returnValueForMissingStub: null, ); @override - set timestamp(DateTime? _timestamp) => super.noSuchMethod( + set timestamp(DateTime? value) => super.noSuchMethod( Invocation.setter( #timestamp, - _timestamp, + value, ), returnValueForMissingStub: null, ); @override - set platform(String? _platform) => super.noSuchMethod( + set platform(String? value) => super.noSuchMethod( Invocation.setter( #platform, - _platform, + value, ), returnValueForMissingStub: null, ); @override - set logger(String? _logger) => super.noSuchMethod( + set logger(String? value) => super.noSuchMethod( Invocation.setter( #logger, - _logger, + value, ), returnValueForMissingStub: null, ); @override - set serverName(String? _serverName) => super.noSuchMethod( + set serverName(String? value) => super.noSuchMethod( Invocation.setter( #serverName, - _serverName, + value, ), returnValueForMissingStub: null, ); @override - set release(String? _release) => super.noSuchMethod( + set release(String? value) => super.noSuchMethod( Invocation.setter( #release, - _release, + value, ), returnValueForMissingStub: null, ); @override - set dist(String? _dist) => super.noSuchMethod( + set dist(String? value) => super.noSuchMethod( Invocation.setter( #dist, - _dist, + value, ), returnValueForMissingStub: null, ); @override - set environment(String? _environment) => super.noSuchMethod( + set environment(String? value) => super.noSuchMethod( Invocation.setter( #environment, - _environment, + value, ), returnValueForMissingStub: null, ); @override - set modules(Map? _modules) => super.noSuchMethod( + set modules(Map? value) => super.noSuchMethod( Invocation.setter( #modules, - _modules, + value, ), returnValueForMissingStub: null, ); @override - set message(_i2.SentryMessage? _message) => super.noSuchMethod( + set message(_i2.SentryMessage? value) => super.noSuchMethod( Invocation.setter( #message, - _message, + value, ), returnValueForMissingStub: null, ); @override - set exceptions(List<_i2.SentryException>? _exceptions) => super.noSuchMethod( + set exceptions(List<_i2.SentryException>? value) => super.noSuchMethod( Invocation.setter( #exceptions, - _exceptions, + value, ), returnValueForMissingStub: null, ); @override - set threads(List<_i2.SentryThread>? _threads) => super.noSuchMethod( + set threads(List<_i2.SentryThread>? value) => super.noSuchMethod( Invocation.setter( #threads, - _threads, + value, ), returnValueForMissingStub: null, ); @override - set transaction(String? _transaction) => super.noSuchMethod( + set transaction(String? value) => super.noSuchMethod( Invocation.setter( #transaction, - _transaction, + value, ), returnValueForMissingStub: null, ); @override - set level(_i2.SentryLevel? _level) => super.noSuchMethod( + set level(_i2.SentryLevel? value) => super.noSuchMethod( Invocation.setter( #level, - _level, + value, ), returnValueForMissingStub: null, ); @override - set culprit(String? _culprit) => super.noSuchMethod( + set culprit(String? value) => super.noSuchMethod( Invocation.setter( #culprit, - _culprit, + value, ), returnValueForMissingStub: null, ); @override - set tags(Map? _tags) => super.noSuchMethod( + set tags(Map? value) => super.noSuchMethod( Invocation.setter( #tags, - _tags, + value, ), returnValueForMissingStub: null, ); @override - set extra(Map? _extra) => super.noSuchMethod( + set extra(Map? value) => super.noSuchMethod( Invocation.setter( #extra, - _extra, + value, ), returnValueForMissingStub: null, ); @override - set breadcrumbs(List<_i2.Breadcrumb>? _breadcrumbs) => super.noSuchMethod( + set breadcrumbs(List<_i2.Breadcrumb>? value) => super.noSuchMethod( Invocation.setter( #breadcrumbs, - _breadcrumbs, + value, ), returnValueForMissingStub: null, ); @override - set user(_i2.SentryUser? _user) => super.noSuchMethod( + set user(_i2.SentryUser? value) => super.noSuchMethod( Invocation.setter( #user, - _user, + value, ), returnValueForMissingStub: null, ); @override - set contexts(_i2.Contexts? _contexts) => super.noSuchMethod( + set contexts(_i2.Contexts? value) => super.noSuchMethod( Invocation.setter( #contexts, - _contexts, + value, ), returnValueForMissingStub: null, ); @override - set fingerprint(List? _fingerprint) => super.noSuchMethod( + set fingerprint(List? value) => super.noSuchMethod( Invocation.setter( #fingerprint, - _fingerprint, + value, ), returnValueForMissingStub: null, ); @override - set sdk(_i2.SdkVersion? _sdk) => super.noSuchMethod( + set sdk(_i2.SdkVersion? value) => super.noSuchMethod( Invocation.setter( #sdk, - _sdk, + value, ), returnValueForMissingStub: null, ); @override - set request(_i2.SentryRequest? _request) => super.noSuchMethod( + set request(_i2.SentryRequest? value) => super.noSuchMethod( Invocation.setter( #request, - _request, + value, ), returnValueForMissingStub: null, ); @override - set debugMeta(_i2.DebugMeta? _debugMeta) => super.noSuchMethod( + set debugMeta(_i2.DebugMeta? value) => super.noSuchMethod( Invocation.setter( #debugMeta, - _debugMeta, + value, ), returnValueForMissingStub: null, ); @override - set type(String? _type) => super.noSuchMethod( + set type(String? value) => super.noSuchMethod( Invocation.setter( #type, - _type, + value, ), returnValueForMissingStub: null, ); @@ -1417,7 +1429,7 @@ class MockSentrySpan extends _i1.Mock implements _i2.SentrySpan { ); @override - _i11.Future finish({ + _i12.Future finish({ _i2.SpanStatus? status, DateTime? endTimestamp, _i2.Hint? hint, @@ -1432,9 +1444,9 @@ class MockSentrySpan extends _i1.Mock implements _i2.SentrySpan { #hint: hint, }, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void removeData(String? key) => super.noSuchMethod( @@ -1575,7 +1587,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { } @override - _i11.Future<_i2.SentryId> captureEvent( + _i12.Future<_i2.SentryId> captureEvent( _i2.SentryEvent? event, { _i2.Scope? scope, dynamic stackTrace, @@ -1591,7 +1603,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureEvent, @@ -1603,10 +1615,10 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureException( + _i12.Future<_i2.SentryId> captureException( dynamic throwable, { dynamic stackTrace, _i2.Scope? scope, @@ -1622,7 +1634,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureException, @@ -1634,10 +1646,10 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureMessage( + _i12.Future<_i2.SentryId> captureMessage( String? formatted, { _i2.SentryLevel? level, String? template, @@ -1657,7 +1669,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureMessage, @@ -1671,10 +1683,10 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureTransaction( + _i12.Future<_i2.SentryId> captureTransaction( _i2.SentryTransaction? transaction, { _i2.Scope? scope, _i2.SentryTraceContextHeader? traceContext, @@ -1690,7 +1702,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureTransaction, @@ -1702,20 +1714,20 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId?> captureEnvelope(_i2.SentryEnvelope? envelope) => + _i12.Future<_i2.SentryId?> captureEnvelope(_i2.SentryEnvelope? envelope) => (super.noSuchMethod( Invocation.method( #captureEnvelope, [envelope], ), - returnValue: _i11.Future<_i2.SentryId?>.value(), - ) as _i11.Future<_i2.SentryId?>); + returnValue: _i12.Future<_i2.SentryId?>.value(), + ) as _i12.Future<_i2.SentryId?>); @override - _i11.Future<_i2.SentryId> captureFeedback( + _i12.Future<_i2.SentryId> captureFeedback( _i2.SentryFeedback? feedback, { _i2.Scope? scope, _i2.Hint? hint, @@ -1729,7 +1741,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureFeedback, @@ -1740,10 +1752,10 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.FutureOr captureLog( + _i12.FutureOr captureLog( _i2.SentryLog? log, { _i2.Scope? scope, }) => @@ -1751,16 +1763,22 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { #captureLog, [log], {#scope: scope}, - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - void close() => super.noSuchMethod( + _i12.Future captureMetric( + _i17.SentryMetric? metric, { + _i2.Scope? scope, + }) => + (super.noSuchMethod( Invocation.method( - #close, - [], + #captureMetric, + [metric], + {#scope: scope}, ), - returnValueForMissingStub: null, - ); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); } /// A class which mocks [MethodChannel]. @@ -1774,7 +1792,7 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { @override String get name => (super.noSuchMethod( Invocation.getter(#name), - returnValue: _i14.dummyValue( + returnValue: _i15.dummyValue( this, Invocation.getter(#name), ), @@ -1799,7 +1817,7 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { ) as _i4.BinaryMessenger); @override - _i11.Future invokeMethod( + _i12.Future invokeMethod( String? method, [ dynamic arguments, ]) => @@ -1811,11 +1829,11 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { arguments, ], ), - returnValue: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + ) as _i12.Future); @override - _i11.Future?> invokeListMethod( + _i12.Future?> invokeListMethod( String? method, [ dynamic arguments, ]) => @@ -1827,11 +1845,11 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { arguments, ], ), - returnValue: _i11.Future?>.value(), - ) as _i11.Future?>); + returnValue: _i12.Future?>.value(), + ) as _i12.Future?>); @override - _i11.Future?> invokeMapMethod( + _i12.Future?> invokeMapMethod( String? method, [ dynamic arguments, ]) => @@ -1843,12 +1861,12 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { arguments, ], ), - returnValue: _i11.Future?>.value(), - ) as _i11.Future?>); + returnValue: _i12.Future?>.value(), + ) as _i12.Future?>); @override void setMethodCallHandler( - _i11.Future Function(_i4.MethodCall)? handler) => + _i12.Future Function(_i4.MethodCall)? handler) => super.noSuchMethod( Invocation.method( #setMethodCallHandler, @@ -1862,7 +1880,7 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { /// /// See the documentation for Mockito's code generation for more information. class MockSentryNativeBinding extends _i1.Mock - implements _i16.SentryNativeBinding { + implements _i18.SentryNativeBinding { MockSentryNativeBinding() { _i1.throwOnMissingStub(this); } @@ -1886,15 +1904,15 @@ class MockSentryNativeBinding extends _i1.Mock ) as bool); @override - _i11.FutureOr init(_i2.Hub? hub) => + _i12.FutureOr init(_i2.Hub? hub) => (super.noSuchMethod(Invocation.method( #init, [hub], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr captureEnvelope( - _i17.Uint8List? envelopeData, + _i12.FutureOr captureEnvelope( + _i19.Uint8List? envelopeData, bool? containsUnhandledException, ) => (super.noSuchMethod(Invocation.method( @@ -1903,24 +1921,24 @@ class MockSentryNativeBinding extends _i1.Mock envelopeData, containsUnhandledException, ], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr captureStructuredEnvelope(_i2.SentryEnvelope? envelope) => + _i12.FutureOr captureStructuredEnvelope(_i2.SentryEnvelope? envelope) => (super.noSuchMethod(Invocation.method( #captureStructuredEnvelope, [envelope], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr addBreadcrumb(_i2.Breadcrumb? breadcrumb) => + _i12.FutureOr addBreadcrumb(_i2.Breadcrumb? breadcrumb) => (super.noSuchMethod(Invocation.method( #addBreadcrumb, [breadcrumb], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr setContexts( + _i12.FutureOr setContexts( String? key, dynamic value, ) => @@ -1930,17 +1948,17 @@ class MockSentryNativeBinding extends _i1.Mock key, value, ], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr removeContexts(String? key) => + _i12.FutureOr removeContexts(String? key) => (super.noSuchMethod(Invocation.method( #removeContexts, [key], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr setExtra( + _i12.FutureOr setExtra( String? key, dynamic value, ) => @@ -1950,17 +1968,17 @@ class MockSentryNativeBinding extends _i1.Mock key, value, ], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr removeExtra(String? key) => + _i12.FutureOr removeExtra(String? key) => (super.noSuchMethod(Invocation.method( #removeExtra, [key], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr setTag( + _i12.FutureOr setTag( String? key, String? value, ) => @@ -1970,14 +1988,14 @@ class MockSentryNativeBinding extends _i1.Mock key, value, ], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr removeTag(String? key) => + _i12.FutureOr removeTag(String? key) => (super.noSuchMethod(Invocation.method( #removeTag, [key], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override int? startProfiler(_i2.SentryId? traceId) => @@ -1987,14 +2005,14 @@ class MockSentryNativeBinding extends _i1.Mock )) as int?); @override - _i11.FutureOr discardProfiler(_i2.SentryId? traceId) => + _i12.FutureOr discardProfiler(_i2.SentryId? traceId) => (super.noSuchMethod(Invocation.method( #discardProfiler, [traceId], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr?> collectProfile( + _i12.FutureOr?> collectProfile( _i2.SentryId? traceId, int? startTimeNs, int? endTimeNs, @@ -2006,64 +2024,64 @@ class MockSentryNativeBinding extends _i1.Mock startTimeNs, endTimeNs, ], - )) as _i11.FutureOr?>); + )) as _i12.FutureOr?>); @override - _i11.FutureOr?> loadDebugImages( + _i12.FutureOr?> loadDebugImages( _i2.SentryStackTrace? stackTrace) => (super.noSuchMethod(Invocation.method( #loadDebugImages, [stackTrace], - )) as _i11.FutureOr?>); + )) as _i12.FutureOr?>); @override - _i11.FutureOr setReplayConfig(_i18.ReplayConfig? config) => + _i12.FutureOr setReplayConfig(_i20.ReplayConfig? config) => (super.noSuchMethod(Invocation.method( #setReplayConfig, [config], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override - _i11.FutureOr<_i2.SentryId> captureReplay() => (super.noSuchMethod( + _i12.FutureOr<_i2.SentryId> captureReplay() => (super.noSuchMethod( Invocation.method( #captureReplay, [], ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureReplay, [], ), )), - ) as _i11.FutureOr<_i2.SentryId>); + ) as _i12.FutureOr<_i2.SentryId>); @override - _i11.FutureOr startSession({bool? ignoreDuration = false}) => + _i12.FutureOr startSession({bool? ignoreDuration = false}) => (super.noSuchMethod(Invocation.method( #startSession, [], {#ignoreDuration: ignoreDuration}, - )) as _i11.FutureOr); + )) as _i12.FutureOr); } /// A class which mocks [SentryDelayedFramesTracker]. /// /// See the documentation for Mockito's code generation for more information. class MockSentryDelayedFramesTracker extends _i1.Mock - implements _i19.SentryDelayedFramesTracker { + implements _i21.SentryDelayedFramesTracker { MockSentryDelayedFramesTracker() { _i1.throwOnMissingStub(this); } @override - List<_i19.SentryFrameTiming> get delayedFrames => (super.noSuchMethod( + List<_i21.SentryFrameTiming> get delayedFrames => (super.noSuchMethod( Invocation.getter(#delayedFrames), - returnValue: <_i19.SentryFrameTiming>[], - ) as List<_i19.SentryFrameTiming>); + returnValue: <_i21.SentryFrameTiming>[], + ) as List<_i21.SentryFrameTiming>); @override - List<_i19.SentryFrameTiming> getFramesIntersecting({ + List<_i21.SentryFrameTiming> getFramesIntersecting({ required DateTime? startTimestamp, required DateTime? endTimestamp, }) => @@ -2076,8 +2094,8 @@ class MockSentryDelayedFramesTracker extends _i1.Mock #endTimestamp: endTimestamp, }, ), - returnValue: <_i19.SentryFrameTiming>[], - ) as List<_i19.SentryFrameTiming>); + returnValue: <_i21.SentryFrameTiming>[], + ) as List<_i21.SentryFrameTiming>); @override void addDelayedFrame( @@ -2106,7 +2124,7 @@ class MockSentryDelayedFramesTracker extends _i1.Mock ); @override - _i19.SpanFrameMetrics? getFrameMetrics({ + _i21.SpanFrameMetrics? getFrameMetrics({ required DateTime? spanStartTimestamp, required DateTime? spanEndTimestamp, }) => @@ -2117,7 +2135,7 @@ class MockSentryDelayedFramesTracker extends _i1.Mock #spanStartTimestamp: spanStartTimestamp, #spanEndTimestamp: spanEndTimestamp, }, - )) as _i19.SpanFrameMetrics?); + )) as _i21.SpanFrameMetrics?); @override void clear() => super.noSuchMethod( @@ -2213,6 +2231,15 @@ class MockWidgetsFlutterBinding extends _i1.Mock ), ) as _i7.PointerSignalResolver); + @override + _i7.SamplingClock get samplingClock => (super.noSuchMethod( + Invocation.getter(#samplingClock), + returnValue: _FakeSamplingClock_16( + this, + Invocation.getter(#samplingClock), + ), + ) as _i7.SamplingClock); + @override bool get resamplingEnabled => (super.noSuchMethod( Invocation.getter(#resamplingEnabled), @@ -2222,48 +2249,39 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override Duration get samplingOffset => (super.noSuchMethod( Invocation.getter(#samplingOffset), - returnValue: _FakeDuration_16( + returnValue: _FakeDuration_17( this, Invocation.getter(#samplingOffset), ), ) as Duration); @override - _i7.SamplingClock get samplingClock => (super.noSuchMethod( - Invocation.getter(#samplingClock), - returnValue: _FakeSamplingClock_17( - this, - Invocation.getter(#samplingClock), - ), - ) as _i7.SamplingClock); - - @override - set resamplingEnabled(bool? _resamplingEnabled) => super.noSuchMethod( + set resamplingEnabled(bool? value) => super.noSuchMethod( Invocation.setter( #resamplingEnabled, - _resamplingEnabled, + value, ), returnValueForMissingStub: null, ); @override - set samplingOffset(Duration? _samplingOffset) => super.noSuchMethod( + set samplingOffset(Duration? value) => super.noSuchMethod( Invocation.setter( #samplingOffset, - _samplingOffset, + value, ), returnValueForMissingStub: null, ); @override - _i20.SchedulingStrategy get schedulingStrategy => (super.noSuchMethod( + _i22.SchedulingStrategy get schedulingStrategy => (super.noSuchMethod( Invocation.getter(#schedulingStrategy), returnValue: ({ required int priority, - required _i20.SchedulerBinding scheduler, + required _i22.SchedulerBinding scheduler, }) => false, - ) as _i20.SchedulingStrategy); + ) as _i22.SchedulingStrategy); @override int get transientCallbackCount => (super.noSuchMethod( @@ -2272,10 +2290,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as int); @override - _i11.Future get endOfFrame => (super.noSuchMethod( + _i12.Future get endOfFrame => (super.noSuchMethod( Invocation.getter(#endOfFrame), - returnValue: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + ) as _i12.Future); @override bool get hasScheduledFrame => (super.noSuchMethod( @@ -2284,10 +2302,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - _i20.SchedulerPhase get schedulerPhase => (super.noSuchMethod( + _i22.SchedulerPhase get schedulerPhase => (super.noSuchMethod( Invocation.getter(#schedulerPhase), - returnValue: _i20.SchedulerPhase.idle, - ) as _i20.SchedulerPhase); + returnValue: _i22.SchedulerPhase.idle, + ) as _i22.SchedulerPhase); @override bool get framesEnabled => (super.noSuchMethod( @@ -2298,7 +2316,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override Duration get currentFrameTimeStamp => (super.noSuchMethod( Invocation.getter(#currentFrameTimeStamp), - returnValue: _FakeDuration_16( + returnValue: _FakeDuration_17( this, Invocation.getter(#currentFrameTimeStamp), ), @@ -2307,35 +2325,25 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override Duration get currentSystemFrameTimeStamp => (super.noSuchMethod( Invocation.getter(#currentSystemFrameTimeStamp), - returnValue: _FakeDuration_16( + returnValue: _FakeDuration_17( this, Invocation.getter(#currentSystemFrameTimeStamp), ), ) as Duration); @override - set schedulingStrategy(_i20.SchedulingStrategy? _schedulingStrategy) => - super.noSuchMethod( + set schedulingStrategy(_i22.SchedulingStrategy? value) => super.noSuchMethod( Invocation.setter( #schedulingStrategy, - _schedulingStrategy, + value, ), returnValueForMissingStub: null, ); - @override - _i8.ValueNotifier get accessibilityFocus => (super.noSuchMethod( - Invocation.getter(#accessibilityFocus), - returnValue: _FakeValueNotifier_18( - this, - Invocation.getter(#accessibilityFocus), - ), - ) as _i8.ValueNotifier); - @override _i4.HardwareKeyboard get keyboard => (super.noSuchMethod( Invocation.getter(#keyboard), - returnValue: _FakeHardwareKeyboard_19( + returnValue: _FakeHardwareKeyboard_18( this, Invocation.getter(#keyboard), ), @@ -2344,7 +2352,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override _i4.KeyEventManager get keyEventManager => (super.noSuchMethod( Invocation.getter(#keyEventManager), - returnValue: _FakeKeyEventManager_20( + returnValue: _FakeKeyEventManager_19( this, Invocation.getter(#keyEventManager), ), @@ -2362,12 +2370,21 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override _i6.ChannelBuffers get channelBuffers => (super.noSuchMethod( Invocation.getter(#channelBuffers), - returnValue: _FakeChannelBuffers_21( + returnValue: _FakeChannelBuffers_20( this, Invocation.getter(#channelBuffers), ), ) as _i6.ChannelBuffers); + @override + _i8.ValueNotifier get accessibilityFocus => (super.noSuchMethod( + Invocation.getter(#accessibilityFocus), + returnValue: _FakeValueNotifier_21( + this, + Invocation.getter(#accessibilityFocus), + ), + ) as _i8.ValueNotifier); + @override _i4.RestorationManager get restorationManager => (super.noSuchMethod( Invocation.getter(#restorationManager), @@ -2422,10 +2439,19 @@ class MockWidgetsFlutterBinding extends _i1.Mock returnValue: false, ) as bool); + @override + _i10.MouseTracker get mouseTracker => (super.noSuchMethod( + Invocation.getter(#mouseTracker), + returnValue: _FakeMouseTracker_26( + this, + Invocation.getter(#mouseTracker), + ), + ) as _i10.MouseTracker); + @override _i10.PipelineOwner get pipelineOwner => (super.noSuchMethod( Invocation.getter(#pipelineOwner), - returnValue: _i14.dummyValue<_i10.PipelineOwner>( + returnValue: _i15.dummyValue<_i10.PipelineOwner>( this, Invocation.getter(#pipelineOwner), ), @@ -2434,25 +2460,16 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override _i10.RenderView get renderView => (super.noSuchMethod( Invocation.getter(#renderView), - returnValue: _FakeRenderView_26( + returnValue: _FakeRenderView_27( this, Invocation.getter(#renderView), ), ) as _i10.RenderView); - @override - _i10.MouseTracker get mouseTracker => (super.noSuchMethod( - Invocation.getter(#mouseTracker), - returnValue: _FakeMouseTracker_27( - this, - Invocation.getter(#mouseTracker), - ), - ) as _i10.MouseTracker); - @override _i10.PipelineOwner get rootPipelineOwner => (super.noSuchMethod( Invocation.getter(#rootPipelineOwner), - returnValue: _i14.dummyValue<_i10.PipelineOwner>( + returnValue: _i15.dummyValue<_i10.PipelineOwner>( this, Invocation.getter(#rootPipelineOwner), ), @@ -2470,21 +2487,6 @@ class MockWidgetsFlutterBinding extends _i1.Mock returnValue: false, ) as bool); - @override - _i9.PlatformMenuDelegate get platformMenuDelegate => (super.noSuchMethod( - Invocation.getter(#platformMenuDelegate), - returnValue: _FakePlatformMenuDelegate_28( - this, - Invocation.getter(#platformMenuDelegate), - ), - ) as _i9.PlatformMenuDelegate); - - @override - bool get debugBuildingDirtyElements => (super.noSuchMethod( - Invocation.getter(#debugBuildingDirtyElements), - returnValue: false, - ) as bool); - @override bool get debugShowWidgetInspectorOverride => (super.noSuchMethod( Invocation.getter(#debugShowWidgetInspectorOverride), @@ -2495,7 +2497,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock _i8.ValueNotifier get debugShowWidgetInspectorOverrideNotifier => (super.noSuchMethod( Invocation.getter(#debugShowWidgetInspectorOverrideNotifier), - returnValue: _FakeValueNotifier_18( + returnValue: _FakeValueNotifier_21( this, Invocation.getter(#debugShowWidgetInspectorOverrideNotifier), ), @@ -2505,21 +2507,36 @@ class MockWidgetsFlutterBinding extends _i1.Mock _i8.ValueNotifier get debugWidgetInspectorSelectionOnTapEnabled => (super.noSuchMethod( Invocation.getter(#debugWidgetInspectorSelectionOnTapEnabled), - returnValue: _FakeValueNotifier_18( + returnValue: _FakeValueNotifier_21( this, Invocation.getter(#debugWidgetInspectorSelectionOnTapEnabled), ), ) as _i8.ValueNotifier); + @override + bool get debugExcludeRootWidgetInspector => (super.noSuchMethod( + Invocation.getter(#debugExcludeRootWidgetInspector), + returnValue: false, + ) as bool); + @override _i9.FocusManager get focusManager => (super.noSuchMethod( Invocation.getter(#focusManager), - returnValue: _FakeFocusManager_29( + returnValue: _FakeFocusManager_28( this, Invocation.getter(#focusManager), ), ) as _i9.FocusManager); + @override + _i9.PlatformMenuDelegate get platformMenuDelegate => (super.noSuchMethod( + Invocation.getter(#platformMenuDelegate), + returnValue: _FakePlatformMenuDelegate_29( + this, + Invocation.getter(#platformMenuDelegate), + ), + ) as _i9.PlatformMenuDelegate); + @override bool get firstFrameRasterized => (super.noSuchMethod( Invocation.getter(#firstFrameRasterized), @@ -2527,10 +2544,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - _i11.Future get waitUntilFirstFrameRasterized => (super.noSuchMethod( + _i12.Future get waitUntilFirstFrameRasterized => (super.noSuchMethod( Invocation.getter(#waitUntilFirstFrameRasterized), - returnValue: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + ) as _i12.Future); @override bool get debugDidSendFirstFrameEvent => (super.noSuchMethod( @@ -2538,6 +2555,12 @@ class MockWidgetsFlutterBinding extends _i1.Mock returnValue: false, ) as bool); + @override + bool get debugBuildingDirtyElements => (super.noSuchMethod( + Invocation.getter(#debugBuildingDirtyElements), + returnValue: false, + ) as bool); + @override bool get isRootWidgetAttached => (super.noSuchMethod( Invocation.getter(#isRootWidgetAttached), @@ -2545,30 +2568,56 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - set platformMenuDelegate(_i9.PlatformMenuDelegate? _platformMenuDelegate) => + _i11.WindowingOwner get windowingOwner => (super.noSuchMethod( + Invocation.getter(#windowingOwner), + returnValue: _FakeWindowingOwner_30( + this, + Invocation.getter(#windowingOwner), + ), + ) as _i11.WindowingOwner); + + @override + set debugShowWidgetInspectorOverride(bool? value) => super.noSuchMethod( + Invocation.setter( + #debugShowWidgetInspectorOverride, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set debugExcludeRootWidgetInspector(bool? value) => super.noSuchMethod( + Invocation.setter( + #debugExcludeRootWidgetInspector, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set platformMenuDelegate(_i9.PlatformMenuDelegate? value) => super.noSuchMethod( Invocation.setter( #platformMenuDelegate, - _platformMenuDelegate, + value, ), returnValueForMissingStub: null, ); @override - set debugBuildingDirtyElements(bool? _debugBuildingDirtyElements) => - super.noSuchMethod( + set debugBuildingDirtyElements(bool? value) => super.noSuchMethod( Invocation.setter( #debugBuildingDirtyElements, - _debugBuildingDirtyElements, + value, ), returnValueForMissingStub: null, ); @override - set debugShowWidgetInspectorOverride(bool? value) => super.noSuchMethod( + set windowingOwner(_i11.WindowingOwner? owner) => super.noSuchMethod( Invocation.setter( - #debugShowWidgetInspectorOverride, - value, + #windowingOwner, + owner, ), returnValueForMissingStub: null, ); @@ -2601,15 +2650,15 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future lockEvents(_i11.Future Function()? callback) => + _i12.Future lockEvents(_i12.Future Function()? callback) => (super.noSuchMethod( Invocation.method( #lockEvents, [callback], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void unlocked() => super.noSuchMethod( @@ -2621,24 +2670,24 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future reassembleApplication() => (super.noSuchMethod( + _i12.Future reassembleApplication() => (super.noSuchMethod( Invocation.method( #reassembleApplication, [], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override - _i11.Future performReassemble() => (super.noSuchMethod( + _i12.Future performReassemble() => (super.noSuchMethod( Invocation.method( #performReassemble, [], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void registerSignalServiceExtension({ @@ -2879,11 +2928,11 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future scheduleTask( - _i20.TaskCallback? task, - _i20.Priority? priority, { + _i12.Future scheduleTask( + _i22.TaskCallback? task, + _i22.Priority? priority, { String? debugLabel, - _i21.Flow? flow, + _i23.Flow? flow, }) => (super.noSuchMethod( Invocation.method( @@ -2897,8 +2946,8 @@ class MockWidgetsFlutterBinding extends _i1.Mock #flow: flow, }, ), - returnValue: _i14.ifNotNull( - _i14.dummyValueOrNull( + returnValue: _i15.ifNotNull( + _i15.dummyValueOrNull( this, Invocation.method( #scheduleTask, @@ -2912,9 +2961,9 @@ class MockWidgetsFlutterBinding extends _i1.Mock }, ), ), - (T v) => _i11.Future.value(v), + (T v) => _i12.Future.value(v), ) ?? - _FakeFuture_30( + _FakeFuture_31( this, Invocation.method( #scheduleTask, @@ -2928,7 +2977,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock }, ), ), - ) as _i11.Future); + ) as _i12.Future); @override bool handleEventLoopCallback() => (super.noSuchMethod( @@ -2941,7 +2990,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override int scheduleFrameCallback( - _i20.FrameCallback? callback, { + _i22.FrameCallback? callback, { bool? rescheduling = false, bool? scheduleNewFrame = true, }) => @@ -2995,7 +3044,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - void addPersistentFrameCallback(_i20.FrameCallback? callback) => + void addPersistentFrameCallback(_i22.FrameCallback? callback) => super.noSuchMethod( Invocation.method( #addPersistentFrameCallback, @@ -3006,7 +3055,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override void addPostFrameCallback( - _i20.FrameCallback? callback, { + _i22.FrameCallback? callback, { String? debugLabel = 'callback', }) => super.noSuchMethod( @@ -3082,12 +3131,12 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i20.PerformanceModeRequestHandle? requestPerformanceMode( + _i22.PerformanceModeRequestHandle? requestPerformanceMode( _i6.DartPerformanceMode? mode) => (super.noSuchMethod(Invocation.method( #requestPerformanceMode, [mode], - )) as _i20.PerformanceModeRequestHandle?); + )) as _i22.PerformanceModeRequestHandle?); @override void handleDrawFrame() => super.noSuchMethod( @@ -3123,15 +3172,15 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future handleSystemMessage(Object? systemMessage) => + _i12.Future handleSystemMessage(Object? systemMessage) => (super.noSuchMethod( Invocation.method( #handleSystemMessage, [systemMessage], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void initLicenses() => super.noSuchMethod( @@ -3170,18 +3219,18 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future<_i6.AppExitResponse> handleRequestAppExit() => + _i12.Future<_i6.AppExitResponse> handleRequestAppExit() => (super.noSuchMethod( Invocation.method( #handleRequestAppExit, [], ), returnValue: - _i11.Future<_i6.AppExitResponse>.value(_i6.AppExitResponse.exit), - ) as _i11.Future<_i6.AppExitResponse>); + _i12.Future<_i6.AppExitResponse>.value(_i6.AppExitResponse.exit), + ) as _i12.Future<_i6.AppExitResponse>); @override - _i11.Future<_i6.AppExitResponse> exitApplication( + _i12.Future<_i6.AppExitResponse> exitApplication( _i6.AppExitType? exitType, [ int? exitCode = 0, ]) => @@ -3194,8 +3243,8 @@ class MockWidgetsFlutterBinding extends _i1.Mock ], ), returnValue: - _i11.Future<_i6.AppExitResponse>.value(_i6.AppExitResponse.exit), - ) as _i11.Future<_i6.AppExitResponse>); + _i12.Future<_i6.AppExitResponse>.value(_i6.AppExitResponse.exit), + ) as _i12.Future<_i6.AppExitResponse>); @override _i4.RestorationManager createRestorationManager() => (super.noSuchMethod( @@ -3223,14 +3272,14 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future initializationComplete() => (super.noSuchMethod( + _i12.Future initializationComplete() => (super.noSuchMethod( Invocation.method( #initializationComplete, [], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override _i9.ImageCache createImageCache() => (super.noSuchMethod( @@ -3248,7 +3297,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as _i9.ImageCache); @override - _i11.Future<_i6.Codec> instantiateImageCodecFromBuffer( + _i12.Future<_i6.Codec> instantiateImageCodecFromBuffer( _i6.ImmutableBuffer? buffer, { int? cacheWidth, int? cacheHeight, @@ -3264,7 +3313,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #allowUpscaling: allowUpscaling, }, ), - returnValue: _i11.Future<_i6.Codec>.value(_FakeCodec_31( + returnValue: _i12.Future<_i6.Codec>.value(_FakeCodec_32( this, Invocation.method( #instantiateImageCodecFromBuffer, @@ -3276,10 +3325,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock }, ), )), - ) as _i11.Future<_i6.Codec>); + ) as _i12.Future<_i6.Codec>); @override - _i11.Future<_i6.Codec> instantiateImageCodecWithSize( + _i12.Future<_i6.Codec> instantiateImageCodecWithSize( _i6.ImmutableBuffer? buffer, { _i6.TargetImageSizeCallback? getTargetSize, }) => @@ -3289,7 +3338,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock [buffer], {#getTargetSize: getTargetSize}, ), - returnValue: _i11.Future<_i6.Codec>.value(_FakeCodec_31( + returnValue: _i12.Future<_i6.Codec>.value(_FakeCodec_32( this, Invocation.method( #instantiateImageCodecWithSize, @@ -3297,7 +3346,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock {#getTargetSize: getTargetSize}, ), )), - ) as _i11.Future<_i6.Codec>); + ) as _i12.Future<_i6.Codec>); @override void addSemanticsEnabledListener(_i6.VoidCallback? listener) => @@ -3342,19 +3391,19 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i12.SemanticsHandle ensureSemantics() => (super.noSuchMethod( + _i13.SemanticsHandle ensureSemantics() => (super.noSuchMethod( Invocation.method( #ensureSemantics, [], ), - returnValue: _FakeSemanticsHandle_32( + returnValue: _FakeSemanticsHandle_33( this, Invocation.method( #ensureSemantics, [], ), ), - ) as _i12.SemanticsHandle); + ) as _i13.SemanticsHandle); @override void performSemanticsAction(_i6.SemanticsActionEvent? action) => @@ -3382,7 +3431,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createSemanticsUpdateBuilder, [], ), - returnValue: _FakeSemanticsUpdateBuilder_33( + returnValue: _FakeSemanticsUpdateBuilder_34( this, Invocation.method( #createSemanticsUpdateBuilder, @@ -3397,7 +3446,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createRootPipelineOwner, [], ), - returnValue: _i14.dummyValue<_i10.PipelineOwner>( + returnValue: _i15.dummyValue<_i10.PipelineOwner>( this, Invocation.method( #createRootPipelineOwner, @@ -3432,7 +3481,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createViewConfigurationFor, [renderView], ), - returnValue: _FakeViewConfiguration_34( + returnValue: _FakeViewConfiguration_35( this, Invocation.method( #createViewConfigurationFor, @@ -3447,7 +3496,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createSceneBuilder, [], ), - returnValue: _FakeSceneBuilder_35( + returnValue: _FakeSceneBuilder_36( this, Invocation.method( #createSceneBuilder, @@ -3462,7 +3511,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createPictureRecorder, [], ), - returnValue: _FakePictureRecorder_36( + returnValue: _FakePictureRecorder_37( this, Invocation.method( #createPictureRecorder, @@ -3477,7 +3526,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #createCanvas, [recorder], ), - returnValue: _FakeCanvas_37( + returnValue: _FakeCanvas_38( this, Invocation.method( #createCanvas, @@ -3605,22 +3654,22 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i11.Future handlePopRoute() => (super.noSuchMethod( + _i12.Future handlePopRoute() => (super.noSuchMethod( Invocation.method( #handlePopRoute, [], ), - returnValue: _i11.Future.value(false), - ) as _i11.Future); + returnValue: _i12.Future.value(false), + ) as _i12.Future); @override - _i11.Future handlePushRoute(String? route) => (super.noSuchMethod( + _i12.Future handlePushRoute(String? route) => (super.noSuchMethod( Invocation.method( #handlePushRoute, [route], ), - returnValue: _i11.Future.value(false), - ) as _i11.Future); + returnValue: _i12.Future.value(false), + ) as _i12.Future); @override _i9.Widget wrapWithDefaultView(_i9.Widget? rootWidget) => (super.noSuchMethod( @@ -3628,7 +3677,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock #wrapWithDefaultView, [rootWidget], ), - returnValue: _FakeWidget_38( + returnValue: _FakeWidget_39( this, Invocation.method( #wrapWithDefaultView, @@ -3676,7 +3725,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock /// A class which mocks [SentryJsBinding]. /// /// See the documentation for Mockito's code generation for more information. -class MockSentryJsBinding extends _i1.Mock implements _i22.SentryJsBinding { +class MockSentryJsBinding extends _i1.Mock implements _i24.SentryJsBinding { MockSentryJsBinding() { _i1.throwOnMissingStub(this); } @@ -3748,7 +3797,7 @@ class MockSentryJsBinding extends _i1.Mock implements _i22.SentryJsBinding { /// /// See the documentation for Mockito's code generation for more information. class MockTimeToDisplayTracker extends _i1.Mock - implements _i23.TimeToDisplayTracker { + implements _i25.TimeToDisplayTracker { MockTimeToDisplayTracker() { _i1.throwOnMissingStub(this); } @@ -3756,23 +3805,23 @@ class MockTimeToDisplayTracker extends _i1.Mock @override _i2.SentryFlutterOptions get options => (super.noSuchMethod( Invocation.getter(#options), - returnValue: _FakeSentryFlutterOptions_39( + returnValue: _FakeSentryFlutterOptions_40( this, Invocation.getter(#options), ), ) as _i2.SentryFlutterOptions); @override - set transactionId(_i2.SpanId? _transactionId) => super.noSuchMethod( + set transactionId(_i2.SpanId? value) => super.noSuchMethod( Invocation.setter( #transactionId, - _transactionId, + value, ), returnValueForMissingStub: null, ); @override - _i11.Future track( + _i12.Future track( _i2.ISentrySpan? transaction, { DateTime? ttidEndTimestamp, }) => @@ -3782,12 +3831,12 @@ class MockTimeToDisplayTracker extends _i1.Mock [transaction], {#ttidEndTimestamp: ttidEndTimestamp}, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override - _i11.Future reportFullyDisplayed({ + _i12.Future reportFullyDisplayed({ _i2.SpanId? spanId, DateTime? endTimestamp, }) => @@ -3800,12 +3849,12 @@ class MockTimeToDisplayTracker extends _i1.Mock #endTimestamp: endTimestamp, }, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override - _i11.Future cancelUnfinishedSpans( + _i12.Future cancelUnfinishedSpans( _i3.SentryTracer? transaction, DateTime? endTimestamp, ) => @@ -3817,9 +3866,9 @@ class MockTimeToDisplayTracker extends _i1.Mock endTimestamp, ], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void clear() => super.noSuchMethod( @@ -3835,13 +3884,13 @@ class MockTimeToDisplayTracker extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTimeToInitialDisplayTracker extends _i1.Mock - implements _i24.TimeToInitialDisplayTracker { + implements _i26.TimeToInitialDisplayTracker { MockTimeToInitialDisplayTracker() { _i1.throwOnMissingStub(this); } @override - _i11.Future<_i2.ISentrySpan?> track({ + _i12.Future<_i2.ISentrySpan?> track({ required _i3.SentryTracer? transaction, DateTime? endTimestamp, }) => @@ -3854,8 +3903,8 @@ class MockTimeToInitialDisplayTracker extends _i1.Mock #endTimestamp: endTimestamp, }, ), - returnValue: _i11.Future<_i2.ISentrySpan?>.value(), - ) as _i11.Future<_i2.ISentrySpan?>); + returnValue: _i12.Future<_i2.ISentrySpan?>.value(), + ) as _i12.Future<_i2.ISentrySpan?>); @override void clear() => super.noSuchMethod( @@ -3871,13 +3920,13 @@ class MockTimeToInitialDisplayTracker extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTimeToFullDisplayTracker extends _i1.Mock - implements _i25.TimeToFullDisplayTracker { + implements _i27.TimeToFullDisplayTracker { MockTimeToFullDisplayTracker() { _i1.throwOnMissingStub(this); } @override - _i11.Future track({ + _i12.Future track({ required _i3.SentryTracer? transaction, DateTime? ttidEndTimestamp, DateTime? ttfdEndTimestamp, @@ -3892,12 +3941,12 @@ class MockTimeToFullDisplayTracker extends _i1.Mock #ttfdEndTimestamp: ttfdEndTimestamp, }, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override - _i11.Future reportFullyDisplayed({ + _i12.Future reportFullyDisplayed({ _i2.SpanId? spanId, DateTime? endTimestamp, }) => @@ -3910,8 +3959,8 @@ class MockTimeToFullDisplayTracker extends _i1.Mock #endTimestamp: endTimestamp, }, ), - returnValue: _i11.Future.value(false), - ) as _i11.Future); + returnValue: _i12.Future.value(false), + ) as _i12.Future); @override void clear() => super.noSuchMethod( @@ -3934,7 +3983,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { @override _i2.SentryOptions get options => (super.noSuchMethod( Invocation.getter(#options), - returnValue: _FakeSentryOptions_40( + returnValue: _FakeSentryOptions_41( this, Invocation.getter(#options), ), @@ -3958,14 +4007,14 @@ class MockHub extends _i1.Mock implements _i2.Hub { @override _i2.Scope get scope => (super.noSuchMethod( Invocation.getter(#scope), - returnValue: _FakeScope_41( + returnValue: _FakeScope_42( this, Invocation.getter(#scope), ), ) as _i2.Scope); @override - set profilerFactory(_i15.SentryProfilerFactory? value) => super.noSuchMethod( + set profilerFactory(_i16.SentryProfilerFactory? value) => super.noSuchMethod( Invocation.setter( #profilerFactory, value, @@ -3974,7 +4023,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { ); @override - _i11.Future<_i2.SentryId> captureEvent( + _i12.Future<_i2.SentryId> captureEvent( _i2.SentryEvent? event, { dynamic stackTrace, _i2.Hint? hint, @@ -3990,7 +4039,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureEvent, @@ -4002,10 +4051,10 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureException( + _i12.Future<_i2.SentryId> captureException( dynamic throwable, { dynamic stackTrace, _i2.Hint? hint, @@ -4023,7 +4072,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureException, @@ -4036,10 +4085,10 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureMessage( + _i12.Future<_i2.SentryId> captureMessage( String? message, { _i2.SentryLevel? level, String? template, @@ -4059,7 +4108,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureMessage, @@ -4073,10 +4122,10 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.Future<_i2.SentryId> captureFeedback( + _i12.Future<_i2.SentryId> captureFeedback( _i2.SentryFeedback? feedback, { _i2.Hint? hint, _i2.ScopeCallback? withScope, @@ -4090,7 +4139,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureFeedback, @@ -4101,17 +4150,47 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override - _i11.FutureOr captureLog(_i2.SentryLog? log) => + _i12.FutureOr captureLog(_i2.SentryLog? log) => (super.noSuchMethod(Invocation.method( #captureLog, [log], - )) as _i11.FutureOr); + )) as _i12.FutureOr); + + @override + _i12.Future captureMetric(_i17.SentryMetric? metric) => + (super.noSuchMethod( + Invocation.method( + #captureMetric, + [metric], + ), + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); + + @override + void setAttributes(Map? attributes) => + super.noSuchMethod( + Invocation.method( + #setAttributes, + [attributes], + ), + returnValueForMissingStub: null, + ); + + @override + void removeAttribute(String? key) => super.noSuchMethod( + Invocation.method( + #removeAttribute, + [key], + ), + returnValueForMissingStub: null, + ); @override - _i11.Future addBreadcrumb( + _i12.Future addBreadcrumb( _i2.Breadcrumb? crumb, { _i2.Hint? hint, }) => @@ -4121,9 +4200,9 @@ class MockHub extends _i1.Mock implements _i2.Hub { [crumb], {#hint: hint}, ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override void bindClient(_i2.SentryClient? client) => super.noSuchMethod( @@ -4140,7 +4219,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #clone, [], ), - returnValue: _FakeHub_42( + returnValue: _FakeHub_43( this, Invocation.method( #clone, @@ -4150,21 +4229,21 @@ class MockHub extends _i1.Mock implements _i2.Hub { ) as _i2.Hub); @override - _i11.Future close() => (super.noSuchMethod( + _i12.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); + returnValue: _i12.Future.value(), + returnValueForMissingStub: _i12.Future.value(), + ) as _i12.Future); @override - _i11.FutureOr configureScope(_i2.ScopeCallback? callback) => + _i12.FutureOr configureScope(_i2.ScopeCallback? callback) => (super.noSuchMethod(Invocation.method( #configureScope, [callback], - )) as _i11.FutureOr); + )) as _i12.FutureOr); @override _i2.ISentrySpan startTransaction( @@ -4197,7 +4276,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #customSamplingContext: customSamplingContext, }, ), - returnValue: _i13.startTransactionShim( + returnValue: _i14.startTransactionShim( name, operation, description: description, @@ -4264,7 +4343,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { ); @override - _i11.Future<_i2.SentryId> captureTransaction( + _i12.Future<_i2.SentryId> captureTransaction( _i2.SentryTransaction? transaction, { _i2.SentryTraceContextHeader? traceContext, _i2.Hint? hint, @@ -4278,7 +4357,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #hint: hint, }, ), - returnValue: _i11.Future<_i2.SentryId>.value(_FakeSentryId_5( + returnValue: _i12.Future<_i2.SentryId>.value(_FakeSentryId_5( this, Invocation.method( #captureTransaction, @@ -4289,7 +4368,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i11.Future<_i2.SentryId>); + ) as _i12.Future<_i2.SentryId>); @override void setSpanContext( diff --git a/packages/flutter/test/screenshot/sentry_screenshot_widget_test.mocks.dart b/packages/flutter/test/screenshot/sentry_screenshot_widget_test.mocks.dart index 8a5e5a357e..4b5bd71e70 100644 --- a/packages/flutter/test/screenshot/sentry_screenshot_widget_test.mocks.dart +++ b/packages/flutter/test/screenshot/sentry_screenshot_widget_test.mocks.dart @@ -21,6 +21,7 @@ import 'sentry_screenshot_widget_test.dart' as _i2; // ignore_for_file: unnecessary_parenthesis // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class +// ignore_for_file: invalid_use_of_internal_member /// A class which mocks [Callbacks]. /// From 584a4b7394ca9c760f6c488b1fac0f4b32cfb660 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 22 Jan 2026 14:47:19 +0100 Subject: [PATCH 26/62] refactor(log): make implementation consistent with metrics and span-first (#3463) Make log implementation consistent with metrics and span-first Co-authored-by: Claude Sonnet 4.5 --- CHANGELOG.md | 4 + packages/dart/lib/sentry.dart | 1 - .../lib/src/logs_enricher_integration.dart | 37 -- packages/dart/lib/src/protocol.dart | 4 +- .../dart/lib/src/sdk_lifecycle_hooks.dart | 4 +- packages/dart/lib/src/sentry.dart | 6 +- packages/dart/lib/src/sentry_client.dart | 107 +---- packages/dart/lib/src/sentry_logger.dart | 95 ---- packages/dart/lib/src/sentry_options.dart | 4 +- .../log/default_logger.dart} | 117 ++++- .../log/log.dart} | 13 +- .../telemetry/log/log_capture_pipeline.dart | 82 ++++ .../log/log_level.dart} | 2 +- .../dart/lib/src/telemetry/log/logger.dart | 96 ++++ .../log/logger_setup_integration.dart | 32 ++ .../lib/src/telemetry/log/noop_logger.dart | 95 ++++ .../src/telemetry/processing/processor.dart | 6 + .../dart/lib/src/telemetry/telemetry.dart | 2 + .../test/logs_enricher_integration_test.dart | 99 ---- packages/dart/test/mocks/mock_hub.dart | 4 +- .../test/mocks/mock_log_capture_pipeline.dart | 19 + .../test/sentry_client_lifecycle_test.dart | 43 -- .../sentry_client_sdk_lifecycle_test.dart | 4 +- packages/dart/test/sentry_client_test.dart | 346 ++------------ .../test/sentry_logger_formatter_test.dart | 429 ------------------ packages/dart/test/sentry_logger_test.dart | 252 ---------- packages/dart/test/sentry_test.dart | 22 - .../log/log_capture_pipeline_test.dart | 257 +++++++++++ .../log/log_level_test.dart} | 2 +- .../log/log_test.dart} | 3 + .../telemetry/log/logger_formatter_test.dart | 295 ++++++++++++ .../log/logger_setup_integration_test.dart | 168 +++++++ .../dart/test/telemetry/log/logger_test.dart | 178 ++++++++ .../processor_integration_test.dart | 1 + .../telemetry/processing/processor_test.dart | 1 + .../load_contexts_integration.dart | 19 +- .../replay_telemetry_integration.dart | 16 +- .../load_contexts_integration_test.dart | 28 +- .../replay_telemetry_integration_test.dart | 2 +- .../logging/lib/src/logging_integration.dart | 2 + 40 files changed, 1435 insertions(+), 1462 deletions(-) delete mode 100644 packages/dart/lib/src/logs_enricher_integration.dart delete mode 100644 packages/dart/lib/src/sentry_logger.dart rename packages/dart/lib/src/{sentry_logger_formatter.dart => telemetry/log/default_logger.dart} (56%) rename packages/dart/lib/src/{protocol/sentry_log.dart => telemetry/log/log.dart} (73%) create mode 100644 packages/dart/lib/src/telemetry/log/log_capture_pipeline.dart rename packages/dart/lib/src/{protocol/sentry_log_level.dart => telemetry/log/log_level.dart} (96%) create mode 100644 packages/dart/lib/src/telemetry/log/logger.dart create mode 100644 packages/dart/lib/src/telemetry/log/logger_setup_integration.dart create mode 100644 packages/dart/lib/src/telemetry/log/noop_logger.dart delete mode 100644 packages/dart/test/logs_enricher_integration_test.dart create mode 100644 packages/dart/test/mocks/mock_log_capture_pipeline.dart delete mode 100644 packages/dart/test/sentry_logger_formatter_test.dart delete mode 100644 packages/dart/test/sentry_logger_test.dart create mode 100644 packages/dart/test/telemetry/log/log_capture_pipeline_test.dart rename packages/dart/test/{protocol/sentry_log_level_test.dart => telemetry/log/log_level_test.dart} (94%) rename packages/dart/test/{protocol/sentry_log_test.dart => telemetry/log/log_test.dart} (95%) create mode 100644 packages/dart/test/telemetry/log/logger_formatter_test.dart create mode 100644 packages/dart/test/telemetry/log/logger_setup_integration_test.dart create mode 100644 packages/dart/test/telemetry/log/logger_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b46c7884b..66e8db206d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ - `Sentry.metrics.count(...)` - `Sentry.metrics.distribution(...)` +### Enhancements + +- Refactor Logging API to be consistent with Metrics ([#3463](https://github.com/getsentry/sentry-dart/pull/3463)) + ### Dependencies - Bump Android SDK from v8.28.0 to v8.30.0 ([#3451](https://github.com/getsentry/sentry-dart/pull/3451)) diff --git a/packages/dart/lib/sentry.dart b/packages/dart/lib/sentry.dart index c809b5e2af..76177fb4e9 100644 --- a/packages/dart/lib/sentry.dart +++ b/packages/dart/lib/sentry.dart @@ -60,7 +60,6 @@ export 'src/utils/tracing_utils.dart'; export 'src/utils/url_details.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/breadcrumb_log_level.dart'; -export 'src/sentry_logger.dart'; export 'src/telemetry/telemetry.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/internal_logger.dart' show SentryInternalLogger; diff --git a/packages/dart/lib/src/logs_enricher_integration.dart b/packages/dart/lib/src/logs_enricher_integration.dart deleted file mode 100644 index ee39b41a96..0000000000 --- a/packages/dart/lib/src/logs_enricher_integration.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'dart:async'; -import 'package:meta/meta.dart'; - -import 'sdk_lifecycle_hooks.dart'; -import 'utils/os_utils.dart'; -import 'integration.dart'; -import 'hub.dart'; -import 'protocol/sentry_attribute.dart'; -import 'sentry_options.dart'; - -@internal -class LogsEnricherIntegration extends Integration { - static const integrationName = 'LogsEnricher'; - - @override - FutureOr call(Hub hub, SentryOptions options) { - if (options.enableLogs) { - options.lifecycleRegistry.registerCallback( - (event) async { - final os = getSentryOperatingSystem(); - - if (os.name != null) { - event.log.attributes['os.name'] = SentryAttribute.string( - os.name ?? '', - ); - } - if (os.version != null) { - event.log.attributes['os.version'] = SentryAttribute.string( - os.version ?? '', - ); - } - }, - ); - options.sdk.addIntegration(integrationName); - } - } -} diff --git a/packages/dart/lib/src/protocol.dart b/packages/dart/lib/src/protocol.dart index cb94d143b7..7347c0e88a 100644 --- a/packages/dart/lib/src/protocol.dart +++ b/packages/dart/lib/src/protocol.dart @@ -41,6 +41,6 @@ export 'protocol/span_status.dart'; export 'sentry_event_like.dart'; export 'protocol/sentry_feature_flag.dart'; export 'protocol/sentry_feature_flags.dart'; -export 'protocol/sentry_log.dart'; -export 'protocol/sentry_log_level.dart'; +export 'telemetry/log/log.dart'; +export 'telemetry/log/log_level.dart'; export 'protocol/sentry_attribute.dart'; diff --git a/packages/dart/lib/src/sdk_lifecycle_hooks.dart b/packages/dart/lib/src/sdk_lifecycle_hooks.dart index c0cbcaf343..36912dc523 100644 --- a/packages/dart/lib/src/sdk_lifecycle_hooks.dart +++ b/packages/dart/lib/src/sdk_lifecycle_hooks.dart @@ -67,8 +67,8 @@ class SdkLifecycleRegistry { } @internal -class OnBeforeCaptureLog extends SdkLifecycleEvent { - OnBeforeCaptureLog(this.log); +class OnProcessLog extends SdkLifecycleEvent { + OnProcessLog(this.log); final SentryLog log; } diff --git a/packages/dart/lib/src/sentry.dart b/packages/dart/lib/src/sentry.dart index 8e598c9b4b..9c658e5643 100644 --- a/packages/dart/lib/src/sentry.dart +++ b/packages/dart/lib/src/sentry.dart @@ -30,8 +30,8 @@ import 'tracing.dart'; import 'transport/data_category.dart'; import 'transport/task_queue.dart'; import 'feature_flags_integration.dart'; -import 'sentry_logger.dart'; -import 'logs_enricher_integration.dart'; +import 'telemetry/log/logger.dart'; +import 'telemetry/log/logger_setup_integration.dart'; /// Configuration options callback typedef OptionsConfiguration = FutureOr Function(SentryOptions); @@ -113,8 +113,8 @@ class Sentry { } options.addIntegration(MetricsSetupIntegration()); + options.addIntegration(LoggerSetupIntegration()); options.addIntegration(FeatureFlagsIntegration()); - options.addIntegration(LogsEnricherIntegration()); options.addIntegration(InMemoryTelemetryProcessorIntegration()); options.addEventProcessor(EnricherEventProcessor(options)); diff --git a/packages/dart/lib/src/sentry_client.dart b/packages/dart/lib/src/sentry_client.dart index bcd4a45419..af9850f847 100644 --- a/packages/dart/lib/src/sentry_client.dart +++ b/packages/dart/lib/src/sentry_client.dart @@ -18,6 +18,7 @@ import 'sentry_exception_factory.dart'; import 'sentry_options.dart'; import 'sentry_stack_trace_factory.dart'; import 'sentry_trace_context_header.dart'; +import 'telemetry/log/log_capture_pipeline.dart'; import 'telemetry/metric/metric.dart'; import 'telemetry/metric/metric_capture_pipeline.dart'; import 'transport/client_report_transport.dart'; @@ -44,6 +45,7 @@ String get defaultIpAddress => _defaultIpAddress; class SentryClient { final SentryOptions _options; final Random? _random; + final LogCapturePipeline _logCapturePipeline; final MetricCapturePipeline _metricCapturePipeline; static final _emptySentryId = Future.value(SentryId.empty()); @@ -53,7 +55,8 @@ class SentryClient { /// Instantiates a client using [SentryOptions] factory SentryClient(SentryOptions options, - {MetricCapturePipeline? metricCapturePipeline}) { + {LogCapturePipeline? logCapturePipeline, + MetricCapturePipeline? metricCapturePipeline}) { if (options.sendClientReports) { options.recorder = ClientReportRecorder(options.clock); } @@ -79,11 +82,15 @@ class SentryClient { options.transport = SpotlightHttpTransport(options, options.transport); } return SentryClient._( - options, metricCapturePipeline ?? MetricCapturePipeline(options)); + options, + logCapturePipeline ?? LogCapturePipeline(options), + metricCapturePipeline ?? MetricCapturePipeline(options), + ); } /// Instantiates a client using [SentryOptions] - SentryClient._(this._options, this._metricCapturePipeline) + SentryClient._( + this._options, this._logCapturePipeline, this._metricCapturePipeline) : _random = _options.sampleRate == null ? null : Random(); /// Reports an [event] to Sentry.io. @@ -495,98 +502,8 @@ class SentryClient { } @internal - FutureOr captureLog( - SentryLog log, { - Scope? scope, - }) async { - if (!_options.enableLogs) { - return; - } - - if (scope != null) { - final merged = Map.of(scope.attributes)..addAll(log.attributes); - log.attributes = merged; - } - - log.attributes['sentry.sdk.name'] = SentryAttribute.string( - _options.sdk.name, - ); - log.attributes['sentry.sdk.version'] = SentryAttribute.string( - _options.sdk.version, - ); - final environment = _options.environment; - if (environment != null) { - log.attributes['sentry.environment'] = SentryAttribute.string( - environment, - ); - } - final release = _options.release; - if (release != null) { - log.attributes['sentry.release'] = SentryAttribute.string( - release, - ); - } - - final propagationContext = scope?.propagationContext; - if (propagationContext != null) { - log.traceId = propagationContext.traceId; - } - final span = scope?.span; - if (span != null) { - log.attributes['sentry.trace.parent_span_id'] = SentryAttribute.string( - span.context.spanId.toString(), - ); - } - - final user = scope?.user; - final id = user?.id; - final email = user?.email; - final name = user?.name; - if (id != null) { - log.attributes['user.id'] = SentryAttribute.string(id); - } - if (name != null) { - log.attributes['user.name'] = SentryAttribute.string(name); - } - if (email != null) { - log.attributes['user.email'] = SentryAttribute.string(email); - } - - final beforeSendLog = _options.beforeSendLog; - SentryLog? processedLog = log; - if (beforeSendLog != null) { - try { - final callbackResult = beforeSendLog(log); - - if (callbackResult is Future) { - processedLog = await callbackResult; - } else { - processedLog = callbackResult; - } - } catch (exception, stackTrace) { - _options.log( - SentryLevel.error, - 'The beforeSendLog callback threw an exception', - exception: exception, - stackTrace: stackTrace, - ); - if (_options.automatedTestMode) { - rethrow; - } - } - } - - if (processedLog != null) { - await _options.lifecycleRegistry - .dispatchCallback(OnBeforeCaptureLog(processedLog)); - _options.telemetryProcessor.addLog(processedLog); - } else { - _options.recorder.recordLostEvent( - DiscardReason.beforeSend, - DataCategory.logItem, - ); - } - } + FutureOr captureLog(SentryLog log, {Scope? scope}) => + _logCapturePipeline.captureLog(log, scope: scope); Future captureMetric(SentryMetric metric, {Scope? scope}) => _metricCapturePipeline.captureMetric(metric, scope: scope); diff --git a/packages/dart/lib/src/sentry_logger.dart b/packages/dart/lib/src/sentry_logger.dart deleted file mode 100644 index a643ac8eec..0000000000 --- a/packages/dart/lib/src/sentry_logger.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:async'; -import 'hub.dart'; -import 'hub_adapter.dart'; -import 'protocol/sentry_log.dart'; -import 'protocol/sentry_log_level.dart'; -import 'protocol/sentry_attribute.dart'; -import 'sentry_options.dart'; -import 'sentry_logger_formatter.dart'; -import 'utils.dart'; - -class SentryLogger { - SentryLogger(this._clock, {Hub? hub}) : _hub = hub ?? HubAdapter(); - - final ClockProvider _clock; - final Hub _hub; - - late final fmt = SentryLoggerFormatter(this); - - FutureOr trace( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.trace, body, attributes: attributes); - } - - FutureOr debug( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.debug, body, attributes: attributes); - } - - FutureOr info( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.info, body, attributes: attributes); - } - - FutureOr warn( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.warn, body, attributes: attributes); - } - - FutureOr error( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.error, body, attributes: attributes); - } - - FutureOr fatal( - String body, { - Map? attributes, - }) { - return _captureLog(SentryLogLevel.fatal, body, attributes: attributes); - } - - // Helper - - FutureOr _captureLog( - SentryLogLevel level, - String body, { - Map? attributes, - }) { - final log = SentryLog( - timestamp: _clock(), - level: level, - body: body, - attributes: attributes ?? {}, - ); - - _hub.options.log( - level.toSentryLevel(), - _formatLogMessage(level, body, attributes ?? {}), - logger: 'sentry_logger', - ); - - return _hub.captureLog(log); - } - - /// Format log message with level and attributes - String _formatLogMessage( - SentryLogLevel level, - String body, - Map? attributes, - ) { - if (attributes == null || attributes.isEmpty) { - return body; - } - return '$body ${attributes.toFormattedString()}'; - } -} diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index d36e29d2c9..bb1cc755b0 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -12,6 +12,7 @@ import 'noop_client.dart'; import 'platform/platform.dart'; import 'sentry_exception_factory.dart'; import 'sentry_stack_trace_factory.dart'; +import 'telemetry/log/noop_logger.dart'; import 'telemetry/metric/noop_metrics.dart'; import 'telemetry/processing/processor.dart'; import 'transport/noop_transport.dart'; @@ -560,7 +561,8 @@ class SentryOptions { /// Enabling this option may change grouping. bool includeModuleInStackTrace = false; - late final SentryLogger logger = SentryLogger(clock); + @internal + late SentryLogger logger = const NoOpSentryLogger(); @internal late SentryMetrics metrics = const NoOpSentryMetrics(); diff --git a/packages/dart/lib/src/sentry_logger_formatter.dart b/packages/dart/lib/src/telemetry/log/default_logger.dart similarity index 56% rename from packages/dart/lib/src/sentry_logger_formatter.dart rename to packages/dart/lib/src/telemetry/log/default_logger.dart index aff7d21e51..40ee263589 100644 --- a/packages/dart/lib/src/sentry_logger_formatter.dart +++ b/packages/dart/lib/src/telemetry/log/default_logger.dart @@ -1,13 +1,113 @@ import 'dart:async'; -import 'protocol/sentry_attribute.dart'; -import 'sentry_template_string.dart'; -import 'sentry_logger.dart'; -class SentryLoggerFormatter { - SentryLoggerFormatter(this._logger); +import '../../../sentry.dart'; +import '../../sentry_template_string.dart'; +import '../../utils/internal_logger.dart'; - final SentryLogger _logger; +typedef CaptureLogCallback = FutureOr Function(SentryLog log); +typedef ScopeProvider = Scope Function(); +final class DefaultSentryLogger implements SentryLogger { + final CaptureLogCallback _captureLogCallback; + final ClockProvider _clockProvider; + final ScopeProvider _scopeProvider; + + late final SentryLoggerFormatter _formatter = + _DefaultSentryLoggerFormatter(this); + + DefaultSentryLogger({ + required CaptureLogCallback captureLogCallback, + required ClockProvider clockProvider, + required ScopeProvider scopeProvider, + }) : _captureLogCallback = captureLogCallback, + _clockProvider = clockProvider, + _scopeProvider = scopeProvider; + + @override + FutureOr trace( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.trace, body, attributes: attributes); + } + + @override + FutureOr debug( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.debug, body, attributes: attributes); + } + + @override + FutureOr info( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.info, body, attributes: attributes); + } + + @override + FutureOr warn( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.warn, body, attributes: attributes); + } + + @override + FutureOr error( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.error, body, attributes: attributes); + } + + @override + FutureOr fatal( + String body, { + Map? attributes, + }) { + return _captureLog(SentryLogLevel.fatal, body, attributes: attributes); + } + + @override + SentryLoggerFormatter get fmt => _formatter; + + // Helpers + + FutureOr _captureLog( + SentryLogLevel level, + String body, { + Map? attributes, + }) { + internalLogger.debug(() => + 'Sentry.logger.${level.value}("$body") called with attributes ${_formatAttributes(attributes)}'); + + final log = SentryLog( + timestamp: _clockProvider(), + level: level, + body: body, + traceId: _scopeProvider().propagationContext.traceId, + spanId: _scopeProvider().span?.context.spanId, + attributes: attributes ?? {}, + ); + + return _captureLogCallback(log); + } + + String _formatAttributes(Map? attributes) { + final formatted = attributes?.toFormattedString() ?? ''; + return formatted.isEmpty ? '' : ' $formatted'; + } +} + +final class _DefaultSentryLoggerFormatter implements SentryLoggerFormatter { + _DefaultSentryLoggerFormatter(this._logger); + + final DefaultSentryLogger _logger; + + @override FutureOr trace( String templateBody, List arguments, { @@ -23,6 +123,7 @@ class SentryLoggerFormatter { ); } + @override FutureOr debug( String templateBody, List arguments, { @@ -38,6 +139,7 @@ class SentryLoggerFormatter { ); } + @override FutureOr info( String templateBody, List arguments, { @@ -53,6 +155,7 @@ class SentryLoggerFormatter { ); } + @override FutureOr warn( String templateBody, List arguments, { @@ -68,6 +171,7 @@ class SentryLoggerFormatter { ); } + @override FutureOr error( String templateBody, List arguments, { @@ -83,6 +187,7 @@ class SentryLoggerFormatter { ); } + @override FutureOr fatal( String templateBody, List arguments, { diff --git a/packages/dart/lib/src/protocol/sentry_log.dart b/packages/dart/lib/src/telemetry/log/log.dart similarity index 73% rename from packages/dart/lib/src/protocol/sentry_log.dart rename to packages/dart/lib/src/telemetry/log/log.dart index 6612b8d700..ac0a211544 100644 --- a/packages/dart/lib/src/protocol/sentry_log.dart +++ b/packages/dart/lib/src/telemetry/log/log.dart @@ -1,10 +1,12 @@ -import 'sentry_attribute.dart'; -import 'sentry_id.dart'; -import 'sentry_log_level.dart'; +import '../../protocol/sentry_attribute.dart'; +import '../../protocol/sentry_id.dart'; +import '../../protocol/span_id.dart'; +import 'log_level.dart'; class SentryLog { DateTime timestamp; - SentryId traceId; + SentryId? traceId; + SpanId? spanId; SentryLogLevel level; String body; Map attributes; @@ -14,10 +16,12 @@ class SentryLog { /// by the time processing completes, it is guaranteed to be a valid non-empty trace id. SentryLog({ required this.timestamp, + // TODO(major-v10): this should be required non-null SentryId? traceId, required this.level, required this.body, required this.attributes, + this.spanId, this.severityNumber, }) : traceId = traceId ?? SentryId.empty(); @@ -25,6 +29,7 @@ class SentryLog { return { 'timestamp': timestamp.toIso8601String(), 'trace_id': traceId.toString(), + if (spanId != null) 'span_id': spanId.toString(), 'level': level.value, 'body': body, 'attributes': diff --git a/packages/dart/lib/src/telemetry/log/log_capture_pipeline.dart b/packages/dart/lib/src/telemetry/log/log_capture_pipeline.dart new file mode 100644 index 0000000000..4abf24b6df --- /dev/null +++ b/packages/dart/lib/src/telemetry/log/log_capture_pipeline.dart @@ -0,0 +1,82 @@ +import 'dart:async'; + +import 'package:meta/meta.dart'; + +import '../../../sentry.dart'; +import '../../client_reports/discard_reason.dart'; +import '../../transport/data_category.dart'; +import '../../utils/internal_logger.dart'; +import '../default_attributes.dart'; + +@internal +class LogCapturePipeline { + final SentryOptions _options; + + LogCapturePipeline(this._options); + + FutureOr captureLog(SentryLog log, {Scope? scope}) async { + if (!_options.enableLogs) { + internalLogger + .debug('$LogCapturePipeline: Logs disabled, dropping ${log.body}'); + return; + } + + try { + if (scope != null) { + // Populate traceId from scope if not already set + // TODO(major-v10): this can be removed once we make the traceId required on the log + if (log.traceId == null || log.traceId == SentryId.empty()) { + log.traceId = scope.propagationContext.traceId; + } + log.attributes.addAllIfAbsent(scope.attributes); + } + + await _options.lifecycleRegistry + .dispatchCallback(OnProcessLog(log)); + + log.attributes.addAllIfAbsent(defaultAttributes(_options, scope: scope)); + + final beforeSendLog = _options.beforeSendLog; + SentryLog? processedLog = log; + if (beforeSendLog != null) { + try { + final callbackResult = beforeSendLog(log); + + if (callbackResult is Future) { + processedLog = await callbackResult; + } else { + processedLog = callbackResult; + } + } catch (exception, stackTrace) { + internalLogger.error( + 'The beforeSendLog callback threw an exception', + error: exception, + stackTrace: stackTrace, + ); + if (_options.automatedTestMode) { + rethrow; + } + } + } + + if (processedLog == null) { + _options.recorder + .recordLostEvent(DiscardReason.beforeSend, DataCategory.logItem); + internalLogger.debug( + '$LogCapturePipeline: Log "${log.body}" dropped by beforeSendLog'); + return; + } + + _options.telemetryProcessor.addLog(processedLog); + } catch (exception, stackTrace) { + internalLogger.error( + 'Error capturing log "${log.body}"', + error: exception, + stackTrace: stackTrace, + ); + if (_options.automatedTestMode) { + rethrow; + } + } + } +} diff --git a/packages/dart/lib/src/protocol/sentry_log_level.dart b/packages/dart/lib/src/telemetry/log/log_level.dart similarity index 96% rename from packages/dart/lib/src/protocol/sentry_log_level.dart rename to packages/dart/lib/src/telemetry/log/log_level.dart index 5fd441e8c9..aa90878613 100644 --- a/packages/dart/lib/src/protocol/sentry_log_level.dart +++ b/packages/dart/lib/src/telemetry/log/log_level.dart @@ -1,4 +1,4 @@ -import 'sentry_level.dart'; +import '../../protocol/sentry_level.dart'; enum SentryLogLevel { trace('trace'), diff --git a/packages/dart/lib/src/telemetry/log/logger.dart b/packages/dart/lib/src/telemetry/log/logger.dart new file mode 100644 index 0000000000..0b8f253832 --- /dev/null +++ b/packages/dart/lib/src/telemetry/log/logger.dart @@ -0,0 +1,96 @@ +import 'dart:async'; + +import '../../../sentry.dart'; + +// TODO(major-v10): refactor FutureOr to void + +/// Interface for emitting custom logs to Sentry. +/// +/// Access via [Sentry.logger]. +abstract interface class SentryLogger { + /// Logs a message at TRACE level. + FutureOr trace( + String body, { + Map? attributes, + }); + + /// Logs a message at DEBUG level. + FutureOr debug( + String body, { + Map? attributes, + }); + + /// Logs a message at INFO level. + FutureOr info( + String body, { + Map? attributes, + }); + + /// Logs a message at WARN level. + FutureOr warn( + String body, { + Map? attributes, + }); + + /// Logs a message at ERROR level. + FutureOr error( + String body, { + Map? attributes, + }); + + /// Logs a message at FATAL level. + FutureOr fatal( + String body, { + Map? attributes, + }); + + /// Provides formatted logging with template strings. + SentryLoggerFormatter get fmt; +} + +/// Interface for formatted logging with template strings. +/// +/// Access via [SentryLogger.fmt]. +abstract interface class SentryLoggerFormatter { + /// Logs a formatted message at TRACE level. + FutureOr trace( + String templateBody, + List arguments, { + Map? attributes, + }); + + /// Logs a formatted message at DEBUG level. + FutureOr debug( + String templateBody, + List arguments, { + Map? attributes, + }); + + /// Logs a formatted message at INFO level. + FutureOr info( + String templateBody, + List arguments, { + Map? attributes, + }); + + /// Logs a formatted message at WARN level. + FutureOr warn( + String templateBody, + List arguments, { + Map? attributes, + }); + + /// Logs a formatted message at ERROR level. + FutureOr error( + String templateBody, + List arguments, { + Map? attributes, + }); + + /// Logs a formatted message at FATAL level. + FutureOr fatal( + String templateBody, + List arguments, { + Map? attributes, + }); +} diff --git a/packages/dart/lib/src/telemetry/log/logger_setup_integration.dart b/packages/dart/lib/src/telemetry/log/logger_setup_integration.dart new file mode 100644 index 0000000000..9eb48cffae --- /dev/null +++ b/packages/dart/lib/src/telemetry/log/logger_setup_integration.dart @@ -0,0 +1,32 @@ +import '../../../sentry.dart'; +import '../../utils/internal_logger.dart'; +import 'default_logger.dart'; +import 'noop_logger.dart'; + +/// Integration that sets up the default Sentry logger implementation. +class LoggerSetupIntegration extends Integration { + static const integrationName = 'LoggerSetup'; + + @override + void call(Hub hub, SentryOptions options) { + if (!options.enableLogs) { + internalLogger.debug('$integrationName: Logs disabled, skipping setup'); + return; + } + + if (options.logger is! NoOpSentryLogger) { + internalLogger.debug( + '$integrationName: Custom logger already configured, skipping setup'); + return; + } + + options.logger = DefaultSentryLogger( + captureLogCallback: hub.captureLog, + clockProvider: options.clock, + scopeProvider: () => hub.scope, + ); + + options.sdk.addIntegration(integrationName); + internalLogger.debug('$integrationName: Logger configured successfully'); + } +} diff --git a/packages/dart/lib/src/telemetry/log/noop_logger.dart b/packages/dart/lib/src/telemetry/log/noop_logger.dart new file mode 100644 index 0000000000..0381bdcb88 --- /dev/null +++ b/packages/dart/lib/src/telemetry/log/noop_logger.dart @@ -0,0 +1,95 @@ +import 'dart:async'; + +import '../../protocol/sentry_attribute.dart'; +import 'logger.dart'; + +final class NoOpSentryLogger implements SentryLogger { + const NoOpSentryLogger(); + + static const _formatter = _NoOpSentryLoggerFormatter(); + + @override + FutureOr trace( + String body, { + Map? attributes, + }) {} + + @override + FutureOr debug( + String body, { + Map? attributes, + }) {} + + @override + FutureOr info( + String body, { + Map? attributes, + }) {} + + @override + FutureOr warn( + String body, { + Map? attributes, + }) {} + + @override + FutureOr error( + String body, { + Map? attributes, + }) {} + + @override + FutureOr fatal( + String body, { + Map? attributes, + }) {} + + @override + SentryLoggerFormatter get fmt => _formatter; +} + +final class _NoOpSentryLoggerFormatter implements SentryLoggerFormatter { + const _NoOpSentryLoggerFormatter(); + + @override + FutureOr trace( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr debug( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr info( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr warn( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr error( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr fatal( + String templateBody, + List arguments, { + Map? attributes, + }) {} +} diff --git a/packages/dart/lib/src/telemetry/processing/processor.dart b/packages/dart/lib/src/telemetry/processing/processor.dart index 778d7accb7..43c2ab32ae 100644 --- a/packages/dart/lib/src/telemetry/processing/processor.dart +++ b/packages/dart/lib/src/telemetry/processing/processor.dart @@ -58,6 +58,9 @@ class DefaultTelemetryProcessor implements TelemetryProcessor { } _logBuffer.add(log); + + internalLogger.debug(() => + '$runtimeType: Log "${log.body}" (${log.level.name}) added to buffer'); } @override @@ -70,6 +73,9 @@ class DefaultTelemetryProcessor implements TelemetryProcessor { } _metricBuffer.add(metric); + + internalLogger.debug(() => + '$runtimeType: Metric "${metric.name}" (${metric.value}) added to buffer'); } @override diff --git a/packages/dart/lib/src/telemetry/telemetry.dart b/packages/dart/lib/src/telemetry/telemetry.dart index f1bbe2e574..98c0f23ba0 100644 --- a/packages/dart/lib/src/telemetry/telemetry.dart +++ b/packages/dart/lib/src/telemetry/telemetry.dart @@ -1,2 +1,4 @@ export 'metric/metrics.dart'; export 'metric/metric.dart'; +export 'log/log.dart'; +export 'log/logger.dart'; diff --git a/packages/dart/test/logs_enricher_integration_test.dart b/packages/dart/test/logs_enricher_integration_test.dart deleted file mode 100644 index 38644c1c74..0000000000 --- a/packages/dart/test/logs_enricher_integration_test.dart +++ /dev/null @@ -1,99 +0,0 @@ -@TestOn('vm') -library; - -import 'package:sentry/src/logs_enricher_integration.dart'; -import 'package:test/test.dart'; -import 'package:sentry/src/hub.dart'; -import 'package:sentry/src/protocol/sentry_log.dart'; -import 'package:sentry/src/protocol/sentry_attribute.dart'; -import 'package:sentry/src/protocol/sentry_id.dart'; -import 'package:sentry/src/protocol/sentry_log_level.dart'; -import 'test_utils.dart'; -import 'package:sentry/src/utils/os_utils.dart'; - -void main() { - SentryLog givenLog() { - return SentryLog( - timestamp: DateTime.now(), - traceId: SentryId.newId(), - level: SentryLogLevel.info, - body: 'test', - attributes: { - 'attribute': SentryAttribute.string('value'), - }, - ); - } - - group('LogsEnricherIntegration', () { - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - test('adds itself to sdk.integrations if enableLogs is true', () { - fixture.options.enableLogs = true; - fixture.addIntegration(); - - expect( - fixture.options.sdk.integrations - .contains(LogsEnricherIntegration.integrationName), - true, - ); - }); - - test('does not add itself to sdk.integrations if enableLogs is false', () { - fixture.options.enableLogs = false; - fixture.addIntegration(); - - expect( - fixture.options.sdk.integrations - .contains(LogsEnricherIntegration.integrationName), - false, - ); - }); - - test( - 'adds os.name and os.version to log attributes on OnBeforeCaptureLog lifecycle event', - () async { - fixture.options.enableLogs = true; - fixture.addIntegration(); - - final log = givenLog(); - await fixture.hub.captureLog(log); - - final os = getSentryOperatingSystem(); - - expect(log.attributes['os.name']?.value, os.name); - expect(log.attributes['os.version']?.value, os.version); - }); - - test( - 'does not add os.name and os.version to log attributes if enableLogs is false', - () async { - fixture.options.enableLogs = false; - fixture.addIntegration(); - - final log = givenLog(); - await fixture.hub.captureLog(log); - - expect(log.attributes['os.name'], isNull); - expect(log.attributes['os.version'], isNull); - }); - }); -} - -class Fixture { - final options = defaultTestOptions(); - late final hub = Hub(options); - late final LogsEnricherIntegration integration; - - Fixture() { - options.enableLogs = true; - integration = LogsEnricherIntegration(); - } - - void addIntegration() { - integration.call(hub, options); - } -} diff --git a/packages/dart/test/mocks/mock_hub.dart b/packages/dart/test/mocks/mock_hub.dart index 6b8d530cae..2499af1a29 100644 --- a/packages/dart/test/mocks/mock_hub.dart +++ b/packages/dart/test/mocks/mock_hub.dart @@ -111,8 +111,8 @@ class MockHub with NoSuchMethodProvider implements Hub { } @override - FutureOr captureLog(SentryLog log) async { - captureLogCalls.add(CaptureLogCall(log, null)); + FutureOr captureLog(SentryLog log, {Scope? scope}) async { + captureLogCalls.add(CaptureLogCall(log, scope)); } @override diff --git a/packages/dart/test/mocks/mock_log_capture_pipeline.dart b/packages/dart/test/mocks/mock_log_capture_pipeline.dart new file mode 100644 index 0000000000..0e88e6b4da --- /dev/null +++ b/packages/dart/test/mocks/mock_log_capture_pipeline.dart @@ -0,0 +1,19 @@ +import 'dart:async'; + +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/log/log_capture_pipeline.dart'; + +import 'mock_sentry_client.dart'; + +class MockLogCapturePipeline extends LogCapturePipeline { + MockLogCapturePipeline(super.options); + + final List captureLogCalls = []; + + int get callCount => captureLogCalls.length; + + @override + FutureOr captureLog(SentryLog log, {Scope? scope}) async { + captureLogCalls.add(CaptureLogCall(log, scope)); + } +} diff --git a/packages/dart/test/sentry_client_lifecycle_test.dart b/packages/dart/test/sentry_client_lifecycle_test.dart index 060cb6e261..9e94217e6c 100644 --- a/packages/dart/test/sentry_client_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_lifecycle_test.dart @@ -16,49 +16,6 @@ void main() { setUp(() => fixture = Fixture()); - group('Logs', () { - SentryLog givenLog() { - return SentryLog( - timestamp: DateTime.now(), - traceId: SentryId.newId(), - level: SentryLogLevel.info, - body: 'test', - attributes: { - 'attribute': SentryAttribute.string('value'), - }, - ); - } - - test('captureLog triggers OnBeforeCaptureLog', () async { - fixture.options.enableLogs = true; - fixture.options.environment = 'test-environment'; - fixture.options.release = 'test-release'; - - final log = givenLog(); - - final scope = Scope(fixture.options); - final span = MockSpan(); - scope.span = span; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - fixture.options.lifecycleRegistry - .registerCallback((event) { - event.log.attributes['test'] = SentryAttribute.string('test-value'); - }); - - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.attributes['test']?.value, "test-value"); - expect(capturedLog.attributes['test']?.type, 'string'); - }); - }); - group('SentryEvent', () { test('captureEvent triggers OnBeforeSendEvent', () async { fixture.options.enableLogs = true; diff --git a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart index 060cb6e261..9de1f753c7 100644 --- a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart @@ -29,7 +29,7 @@ void main() { ); } - test('captureLog triggers OnBeforeCaptureLog', () async { + test('captureLog triggers OnProcessLog', () async { fixture.options.enableLogs = true; fixture.options.environment = 'test-environment'; fixture.options.release = 'test-release'; @@ -45,7 +45,7 @@ void main() { fixture.options.telemetryProcessor = mockProcessor; fixture.options.lifecycleRegistry - .registerCallback((event) { + .registerCallback((event) { event.log.attributes['test'] = SentryAttribute.string('test-value'); }); diff --git a/packages/dart/test/sentry_client_test.dart b/packages/dart/test/sentry_client_test.dart index c2c7eb1e6f..0d7b38e91f 100644 --- a/packages/dart/test/sentry_client_test.dart +++ b/packages/dart/test/sentry_client_test.dart @@ -23,11 +23,11 @@ import 'package:http/http.dart' as http; import 'mocks.dart'; import 'mocks/mock_client_report_recorder.dart'; import 'mocks/mock_hub.dart'; +import 'mocks/mock_log_capture_pipeline.dart'; import 'mocks/mock_metric_capture_pipeline.dart'; import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'test_utils.dart'; -import 'utils/url_details_test.dart'; void main() { group('SentryClient captures message', () { @@ -1721,8 +1721,13 @@ void main() { fixture = Fixture(); }); - SentryLog givenLog() { - return SentryLog( + test('delegates to log pipeline', () async { + final pipeline = MockLogCapturePipeline(fixture.options); + final client = + SentryClient(fixture.options, logCapturePipeline: pipeline); + final scope = Scope(fixture.options); + + final log = SentryLog( timestamp: DateTime.now(), traceId: SentryId.newId(), level: SentryLogLevel.info, @@ -1731,333 +1736,40 @@ void main() { 'attribute': SentryAttribute.string('value'), }, ); - } - - test('disabled by default', () async { - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - - await client.captureLog(log); - - expect(mockProcessor.addedLogs, isEmpty); - }); - - test('should capture logs as envelope', () async { - fixture.options.enableLogs = true; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - - await client.captureLog(log); - - expect(mockProcessor.addedLogs.length, 1); - - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.traceId, log.traceId); - expect(capturedLog.level, log.level); - expect(capturedLog.body, log.body); - expect(capturedLog.attributes['attribute']?.value, - log.attributes['attribute']?.value); - }); - - test('should add additional info to attributes', () async { - fixture.options.enableLogs = true; - fixture.options.environment = 'test-environment'; - fixture.options.release = 'test-release'; - - final log = givenLog(); - - final scope = Scope(fixture.options); - final span = MockSpan(); - scope.span = span; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; await client.captureLog(log, scope: scope); - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect( - capturedLog.attributes['sentry.sdk.name']?.value, - fixture.options.sdk.name, - ); - expect( - capturedLog.attributes['sentry.sdk.name']?.type, - 'string', - ); - expect( - capturedLog.attributes['sentry.sdk.version']?.value, - fixture.options.sdk.version, - ); - expect( - capturedLog.attributes['sentry.sdk.version']?.type, - 'string', - ); - expect( - capturedLog.attributes['sentry.environment']?.value, - fixture.options.environment, - ); - expect( - capturedLog.attributes['sentry.environment']?.type, - 'string', - ); - expect( - capturedLog.attributes['sentry.release']?.value, - fixture.options.release, - ); - expect( - capturedLog.attributes['sentry.release']?.type, - 'string', - ); - expect( - capturedLog.attributes['sentry.trace.parent_span_id']?.value, - span.context.spanId.toString(), - ); - expect( - capturedLog.attributes['sentry.trace.parent_span_id']?.type, - 'string', - ); - }); - - test('should use attributes from given scope', () async { - fixture.options.enableLogs = true; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - final log = givenLog(); - - final scope = Scope(fixture.options); - scope.setAttributes({'from_scope': SentryAttribute.int(12)}); - - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - expect(capturedLog.attributes['from_scope']?.value, 12); - }); - - test('per-log attributes override scope on same key', () async { - fixture.options.enableLogs = true; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - final log = givenLog(); - - final scope = Scope(fixture.options); - scope.setAttributes({ - 'overridden': SentryAttribute.string('fromScope'), - 'kept': SentryAttribute.bool(true), - }); - - log.attributes['overridden'] = SentryAttribute.string('fromLog'); - log.attributes['logOnly'] = SentryAttribute.double(1.23); - - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final captured = mockProcessor.addedLogs.first; - - expect(captured.attributes['overridden']?.value, 'fromLog'); - expect(captured.attributes['kept']?.value, true); - expect(captured.attributes['logOnly']?.type, 'double'); + expect(pipeline.callCount, 1); + expect(pipeline.captureLogCalls.first.log, same(log)); + expect(pipeline.captureLogCalls.first.scope, same(scope)); }); + }); - test('should add user info to attributes', () async { - fixture.options.enableLogs = true; - - final log = givenLog(); - final scope = Scope(fixture.options); - final user = SentryUser( - id: '123', - email: 'test@test.com', - name: 'test-name', - ); - await scope.setUser(user); - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect( - capturedLog.attributes['user.id']?.value, - user.id, - ); - expect( - capturedLog.attributes['user.id']?.type, - 'string', - ); - - expect( - capturedLog.attributes['user.name']?.value, - user.name, - ); - expect( - capturedLog.attributes['user.name']?.type, - 'string', - ); + group('SentryClient captureMetric', () { + late Fixture fixture; - expect( - capturedLog.attributes['user.email']?.value, - user.email, - ); - expect( - capturedLog.attributes['user.email']?.type, - 'string', - ); + setUp(() { + fixture = Fixture(); }); - test('should set trace id from propagation context', () async { - fixture.options.enableLogs = true; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); + test('delegates to metric pipeline', () async { + final pipeline = MockMetricCapturePipeline(fixture.options); + final client = + SentryClient(fixture.options, metricCapturePipeline: pipeline); final scope = Scope(fixture.options); - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.traceId, scope.propagationContext.traceId); - }); - - test( - '$BeforeSendLogCallback returning null drops the log and record it as lost', - () async { - fixture.options.enableLogs = true; - fixture.options.beforeSendLog = (log) => null; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - - await client.captureLog(log); - - expect(mockProcessor.addedLogs.length, 0); - - expect( - fixture.recorder.discardedEvents.first.reason, - DiscardReason.beforeSend, - ); - expect( - fixture.recorder.discardedEvents.first.category, - DataCategory.logItem, + final metric = SentryCounterMetric( + timestamp: DateTime.now().toUtc(), + name: 'test-metric', + value: 1, + traceId: SentryId.newId(), ); - }); - - test('$BeforeSendLogCallback returning a log modifies it', () async { - fixture.options.enableLogs = true; - fixture.options.beforeSendLog = (log) { - log.body = 'modified'; - return log; - }; - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - - await client.captureLog(log); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.body, 'modified'); - }); - - test('$BeforeSendLogCallback returning a log async modifies it', () async { - fixture.options.enableLogs = true; - fixture.options.beforeSendLog = (log) async { - await Future.delayed(Duration(milliseconds: 100)); - log.body = 'modified'; - return log; - }; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - - await client.captureLog(log); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.body, 'modified'); - }); - - test('$BeforeSendLogCallback throwing is caught', () async { - fixture.options.enableLogs = true; - fixture.options.automatedTestMode = false; - - fixture.options.beforeSendLog = (log) { - throw Exception('test'); - }; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - final log = givenLog(); - await client.captureLog(log); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; - - expect(capturedLog.body, 'test'); - }); - - test('OnBeforeCaptureLog lifecycle event is called', () async { - fixture.options.enableLogs = true; - fixture.options.environment = 'test-environment'; - fixture.options.release = 'test-release'; - - final log = givenLog(); - - final scope = Scope(fixture.options); - final span = MockSpan(); - scope.span = span; - - final client = fixture.getSut(); - final mockProcessor = MockTelemetryProcessor(); - fixture.options.telemetryProcessor = mockProcessor; - - fixture.options.lifecycleRegistry - .registerCallback((event) { - event.log.attributes['test'] = SentryAttribute.string('test-value'); - }); - - await client.captureLog(log, scope: scope); - - expect(mockProcessor.addedLogs.length, 1); - final capturedLog = mockProcessor.addedLogs.first; + await client.captureMetric(metric, scope: scope); - expect(capturedLog.attributes['test']?.value, "test-value"); - expect(capturedLog.attributes['test']?.type, 'string'); + expect(pipeline.callCount, 1); + expect(pipeline.captureMetricCalls.first.metric, same(metric)); + expect(pipeline.captureMetricCalls.first.scope, same(scope)); }); }); diff --git a/packages/dart/test/sentry_logger_formatter_test.dart b/packages/dart/test/sentry_logger_formatter_test.dart deleted file mode 100644 index 443fade82a..0000000000 --- a/packages/dart/test/sentry_logger_formatter_test.dart +++ /dev/null @@ -1,429 +0,0 @@ -import 'package:test/test.dart'; -import 'package:sentry/src/sentry_logger_formatter.dart'; -import 'package:sentry/src/sentry_logger.dart'; -import 'package:sentry/src/protocol/sentry_attribute.dart'; - -void main() { - final fixture = Fixture(); - - void verifyPassedAttributes(Map attributes) { - expect(attributes['foo'].type, 'string'); - expect(attributes['foo'].value, 'bar'); - } - - void verifyBasicTemplate(String body, Map attributes) { - expect(body, 'Hello, World!'); - expect(attributes['sentry.message.template'].type, 'string'); - expect(attributes['sentry.message.template'].value, 'Hello, %s!'); - expect(attributes['sentry.message.parameter.0'].type, 'string'); - expect(attributes['sentry.message.parameter.0'].value, 'World'); - verifyPassedAttributes(attributes); - } - - void verifyTemplateWithMultipleArguments( - String body, Map attributes) { - expect(body, 'Name: Alice, Age: 30, Active: true, Score: 95.5'); - expect(attributes['sentry.message.template'].type, 'string'); - expect(attributes['sentry.message.template'].value, - 'Name: %s, Age: %s, Active: %s, Score: %s'); - expect(attributes['sentry.message.parameter.0'].type, 'string'); - expect(attributes['sentry.message.parameter.0'].value, 'Alice'); - expect(attributes['sentry.message.parameter.1'].type, 'integer'); - expect(attributes['sentry.message.parameter.1'].value, 30); - expect(attributes['sentry.message.parameter.2'].type, 'boolean'); - expect(attributes['sentry.message.parameter.2'].value, true); - expect(attributes['sentry.message.parameter.3'].type, 'double'); - expect(attributes['sentry.message.parameter.3'].value, 95.5); - verifyPassedAttributes(attributes); - } - - group('format basic template', () { - test('for trace', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.trace( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.traceCalls.length, 1); - final message = logger.traceCalls[0].message; - final attributes = logger.traceCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - - test('for debug', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.debug( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.debugCalls.length, 1); - final message = logger.debugCalls[0].message; - final attributes = logger.debugCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - - test('for info', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.info( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.infoCalls.length, 1); - final message = logger.infoCalls[0].message; - final attributes = logger.infoCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - - test('for warn', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.warn( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.warnCalls.length, 1); - final message = logger.warnCalls[0].message; - final attributes = logger.warnCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - - test('for error', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.error( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.errorCalls.length, 1); - final message = logger.errorCalls[0].message; - final attributes = logger.errorCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - - test('for fatal', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.fatal( - "Hello, %s!", - ["World"], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.fatalCalls.length, 1); - final message = logger.fatalCalls[0].message; - final attributes = logger.fatalCalls[0].attributes!; - verifyBasicTemplate(message, attributes); - }); - }); - - group('template with multiple arguments', () { - test('for trace', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.trace( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.traceCalls.length, 1); - final message = logger.traceCalls[0].message; - final attributes = logger.traceCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for trace', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.trace( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.traceCalls.length, 1); - final message = logger.traceCalls[0].message; - final attributes = logger.traceCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for debug', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.debug( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.debugCalls.length, 1); - final message = logger.debugCalls[0].message; - final attributes = logger.debugCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for info', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.info( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.infoCalls.length, 1); - final message = logger.infoCalls[0].message; - final attributes = logger.infoCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for warn', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.warn( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.warnCalls.length, 1); - final message = logger.warnCalls[0].message; - final attributes = logger.warnCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for error', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.error( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.errorCalls.length, 1); - final message = logger.errorCalls[0].message; - final attributes = logger.errorCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - - test('for fatal', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.fatal( - "Name: %s, Age: %s, Active: %s, Score: %s", - ['Alice', 30, true, 95.5], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.fatalCalls.length, 1); - final message = logger.fatalCalls[0].message; - final attributes = logger.fatalCalls[0].attributes!; - verifyTemplateWithMultipleArguments(message, attributes); - }); - }); - - group('template with no arguments', () { - test('for trace', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.trace( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.traceCalls.length, 1); - final message = logger.traceCalls[0].message; - final attributes = logger.traceCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - - test('for debug', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.debug( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.debugCalls.length, 1); - final message = logger.debugCalls[0].message; - final attributes = logger.debugCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - - test('for info', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.info( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.infoCalls.length, 1); - final message = logger.infoCalls[0].message; - final attributes = logger.infoCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - - test('for warn', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.warn( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.warnCalls.length, 1); - final message = logger.warnCalls[0].message; - final attributes = logger.warnCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - - test('for error', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.error( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.errorCalls.length, 1); - final message = logger.errorCalls[0].message; - final attributes = logger.errorCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - - test('for fatal', () { - final logger = MockLogger(); - final sut = fixture.getSut(logger); - - sut.fatal( - "Hello, World!", - [], - attributes: {'foo': SentryAttribute.string('bar')}, - ); - - expect(logger.fatalCalls.length, 1); - final message = logger.fatalCalls[0].message; - final attributes = logger.fatalCalls[0].attributes!; - - expect(message, 'Hello, World!'); - expect(attributes['sentry.message.template'], isNull); - expect(attributes['sentry.message.parameter.0'], isNull); - verifyPassedAttributes(attributes); - }); - }); -} - -class Fixture { - SentryLoggerFormatter getSut(SentryLogger logger) { - return SentryLoggerFormatter(logger); - } -} - -class MockLogger implements SentryLogger { - var traceCalls = []; - var debugCalls = []; - var infoCalls = []; - var warnCalls = []; - var errorCalls = []; - var fatalCalls = []; - - @override - SentryLoggerFormatter get fmt => throw UnimplementedError(); - - @override - Future trace(String message, {Map? attributes}) async { - traceCalls.add((message: message, attributes: attributes)); - return; - } - - @override - Future debug(String message, {Map? attributes}) async { - debugCalls.add((message: message, attributes: attributes)); - return; - } - - @override - Future info(String message, {Map? attributes}) async { - infoCalls.add((message: message, attributes: attributes)); - return; - } - - @override - Future warn(String message, {Map? attributes}) async { - warnCalls.add((message: message, attributes: attributes)); - return; - } - - @override - Future error(String message, {Map? attributes}) async { - errorCalls.add((message: message, attributes: attributes)); - return; - } - - @override - Future fatal(String message, {Map? attributes}) async { - fatalCalls.add((message: message, attributes: attributes)); - return; - } -} - -typedef LoggerCall = ({String message, Map? attributes}); diff --git a/packages/dart/test/sentry_logger_test.dart b/packages/dart/test/sentry_logger_test.dart deleted file mode 100644 index 37e760a204..0000000000 --- a/packages/dart/test/sentry_logger_test.dart +++ /dev/null @@ -1,252 +0,0 @@ -import 'package:sentry/sentry.dart'; -import 'package:test/test.dart'; -import 'test_utils.dart'; -import 'mocks/mock_hub.dart'; - -void main() { - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - void verifyCaptureLog(SentryLogLevel level) { - expect(fixture.hub.captureLogCalls.length, 1); - final capturedLog = fixture.hub.captureLogCalls[0].log; - - expect(capturedLog.timestamp, fixture.timestamp); - expect(capturedLog.level, level); - expect(capturedLog.body, 'test'); - expect(capturedLog.attributes, fixture.attributes); - } - - test('sentry logger', () { - final logger = fixture.getSut(); - - logger.info('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.info); - }); - - test('trace', () { - final logger = fixture.getSut(); - - logger.info('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.info); - }); - - test('debug', () { - final logger = fixture.getSut(); - - logger.debug('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.debug); - }); - - test('info', () { - final logger = fixture.getSut(); - - logger.info('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.info); - }); - - test('warn', () { - final logger = fixture.getSut(); - - logger.warn('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.warn); - }); - - test('error', () { - final logger = fixture.getSut(); - - logger.error('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.error); - }); - - test('fatal', () { - final logger = fixture.getSut(); - - logger.fatal('test', attributes: fixture.attributes); - - verifyCaptureLog(SentryLogLevel.fatal); - }); - - test('logs to hub options when provided', () { - final mockLogCallback = _MockSdkLogCallback(); - - // Set the mock log callback on the fixture hub - fixture.hub.options.log = mockLogCallback.call; - fixture.hub.options.debug = true; - fixture.hub.options.diagnosticLevel = SentryLevel.debug; - - final logger = SentryLogger( - () => fixture.timestamp, - hub: fixture.hub, - ); - - logger.trace('test message', attributes: fixture.attributes); - - // Verify that both hub.captureLog and our callback were called - expect(fixture.hub.captureLogCalls.length, 1); - expect(mockLogCallback.calls.length, 1); - - // Verify the captured log has the right content - final capturedLog = fixture.hub.captureLogCalls[0].log; - expect(capturedLog.level, SentryLogLevel.trace); - expect(capturedLog.body, 'test message'); - expect(capturedLog.attributes, fixture.attributes); - - // Verify the log callback was called with the right parameters - final logCall = mockLogCallback.calls[0]; - expect(logCall.level, SentryLevel.debug); // trace maps to debug - expect(logCall.message, - 'test message {"string": "string", "int": 1, "double": 1.23456789, "bool": true, "double_int": 1.0, "nan": NaN, "positive_infinity": Infinity, "negative_infinity": -Infinity}'); - expect(logCall.logger, 'sentry_logger'); - }); - - test('bridges SentryLogLevel to SentryLevel correctly', () { - final mockLogCallback = _MockSdkLogCallback(); - - // Set the mock log callback on the fixture hub's options - fixture.hub.options.log = mockLogCallback.call; - fixture.hub.options.debug = true; - fixture.hub.options.diagnosticLevel = SentryLevel.debug; - - final logger = SentryLogger( - () => fixture.timestamp, - hub: fixture.hub, - ); - - // Test all log levels to ensure proper bridging - logger.trace('trace message'); - logger.debug('debug message'); - logger.info('info message'); - logger.warn('warn message'); - logger.error('error message'); - logger.fatal('fatal message'); - - // Verify that all calls were made to both the hub and the log callback - expect(fixture.hub.captureLogCalls.length, 6); - expect(mockLogCallback.calls.length, 6); - - // Verify the bridging is correct - expect(mockLogCallback.calls[0].level, SentryLevel.debug); // trace -> debug - expect(mockLogCallback.calls[1].level, SentryLevel.debug); // debug -> debug - expect(mockLogCallback.calls[2].level, SentryLevel.info); // info -> info - expect( - mockLogCallback.calls[3].level, SentryLevel.warning); // warn -> warning - expect(mockLogCallback.calls[4].level, SentryLevel.error); // error -> error - expect(mockLogCallback.calls[5].level, SentryLevel.fatal); // fatal -> fatal - }); - - test('handles NaN and infinite values correctly', () { - final mockLogCallback = _MockSdkLogCallback(); - - // Set the mock log callback on the fixture hub's options - fixture.hub.options.log = mockLogCallback.call; - fixture.hub.options.debug = true; - fixture.hub.options.diagnosticLevel = SentryLevel.debug; - - final logger = SentryLogger( - () => fixture.timestamp, - hub: fixture.hub, - ); - - // Test with special double values - final specialAttributes = { - 'nan': SentryAttribute.double(double.nan), - 'positive_infinity': SentryAttribute.double(double.infinity), - 'negative_infinity': SentryAttribute.double(double.negativeInfinity), - }; - - logger.info('special values', attributes: specialAttributes); - - // Verify that both hub.captureLog and our callback were called - expect(fixture.hub.captureLogCalls.length, 1); - expect(mockLogCallback.calls.length, 1); - - // Verify the captured log has the right content - final capturedLog = fixture.hub.captureLogCalls[0].log; - expect(capturedLog.level, SentryLogLevel.info); - expect(capturedLog.body, 'special values'); - expect(capturedLog.attributes, specialAttributes); - - // Verify the log callback was called with the right parameters - final logCall = mockLogCallback.calls[0]; - expect(logCall.level, SentryLevel.info); - expect(logCall.message, - 'special values {"nan": NaN, "positive_infinity": Infinity, "negative_infinity": -Infinity}'); - expect(logCall.logger, 'sentry_logger'); - }); - - // This is mostly an edge case but let's cover it just in case - test('per-log attributes override fmt template attributes on same key', () { - final logger = fixture.getSut(); - - logger.fmt.info( - 'Hello, %s!', - ['World'], - attributes: { - 'sentry.message.template': SentryAttribute.string('OVERRIDE'), - 'sentry.message.parameter.0': SentryAttribute.string('Earth'), - }, - ); - - final attrs = fixture.hub.captureLogCalls[0].log.attributes; - expect(attrs['sentry.message.template']?.value, 'OVERRIDE'); - expect(attrs['sentry.message.parameter.0']?.value, 'Earth'); - }); -} - -class Fixture { - final options = defaultTestOptions(); - final hub = MockHub(); - final timestamp = DateTime.fromMicrosecondsSinceEpoch(0); - - final attributes = { - 'string': SentryAttribute.string('string'), - 'int': SentryAttribute.int(1), - 'double': SentryAttribute.double(1.23456789), - 'bool': SentryAttribute.bool(true), - 'double_int': SentryAttribute.double(1.0), - 'nan': SentryAttribute.double(double.nan), - 'positive_infinity': SentryAttribute.double(double.infinity), - 'negative_infinity': SentryAttribute.double(double.negativeInfinity), - }; - - SentryLogger getSut() { - return SentryLogger(() => timestamp, hub: hub); - } -} - -/// Simple mock for SdkLogCallback to track calls -class _MockSdkLogCallback { - final List<_LogCall> calls = []; - - void call( - SentryLevel level, - String message, { - String? logger, - Object? exception, - StackTrace? stackTrace, - }) { - calls.add(_LogCall(level, message, logger, exception, stackTrace)); - } -} - -/// Data class to store log call information -class _LogCall { - final SentryLevel level; - final String message; - final String? logger; - final Object? exception; - final StackTrace? stackTrace; - - _LogCall( - this.level, this.message, this.logger, this.exception, this.stackTrace); -} diff --git a/packages/dart/test/sentry_test.dart b/packages/dart/test/sentry_test.dart index ab688fdfd7..4c7bac028e 100644 --- a/packages/dart/test/sentry_test.dart +++ b/packages/dart/test/sentry_test.dart @@ -6,7 +6,6 @@ import 'dart:isolate'; import 'package:sentry/sentry.dart'; import 'package:sentry/src/dart_exception_type_identifier.dart'; import 'package:sentry/src/event_processor/deduplication_event_processor.dart'; -import 'package:sentry/src/logs_enricher_integration.dart'; import 'package:sentry/src/feature_flags_integration.dart'; import 'package:sentry/src/telemetry/metric/metrics_setup_integration.dart'; import 'package:sentry/src/telemetry/processing/processor_integration.dart'; @@ -321,27 +320,6 @@ void main() { ); }, onPlatform: {'browser': Skip()}); - test('should add logsEnricherIntegration', () async { - late SentryOptions optionsReference; - final options = defaultTestOptions(); - - await Sentry.init( - options: options, - (options) { - options.dsn = fakeDsn; - optionsReference = options; - }, - appRunner: appRunner, - ); - - expect( - optionsReference.integrations - .whereType() - .length, - 1, - ); - }); - test('should add $InMemoryTelemetryProcessorIntegration', () async { late SentryOptions optionsReference; final options = defaultTestOptions(); diff --git a/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart b/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart new file mode 100644 index 0000000000..5c6179f99e --- /dev/null +++ b/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart @@ -0,0 +1,257 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/client_reports/discard_reason.dart'; +import 'package:sentry/src/telemetry/log/log_capture_pipeline.dart'; +import 'package:sentry/src/transport/data_category.dart'; +import 'package:test/test.dart'; + +import '../../mocks/mock_client_report_recorder.dart'; +import '../../mocks/mock_telemetry_processor.dart'; +import '../../test_utils.dart'; + +void main() { + group('$LogCapturePipeline', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + SentryLog givenLog() { + return SentryLog( + timestamp: DateTime.now(), + traceId: SentryId.newId(), + level: SentryLogLevel.info, + body: 'test', + attributes: { + 'attribute': SentryAttribute.string('value'), + }, + ); + } + + group('when capturing a log', () { + test('forwards to telemetry processor', () async { + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs.length, 1); + expect(fixture.processor.addedLogs.first, same(log)); + }); + + test('adds default attributes', () async { + await fixture.scope.setUser(SentryUser(id: 'user-id')); + fixture.scope.setAttributes({ + 'scope-key': SentryAttribute.string('scope-value'), + }); + + final log = givenLog() + ..attributes['custom'] = SentryAttribute.string('log-value'); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + final attributes = log.attributes; + expect(attributes['scope-key']?.value, 'scope-value'); + expect(attributes['custom']?.value, 'log-value'); + expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, + 'test-env'); + expect(attributes[SemanticAttributesConstants.sentryRelease]?.value, + 'test-release'); + expect(attributes[SemanticAttributesConstants.sentrySdkName]?.value, + fixture.options.sdk.name); + expect(attributes[SemanticAttributesConstants.sentrySdkVersion]?.value, + fixture.options.sdk.version); + expect( + attributes[SemanticAttributesConstants.userId]?.value, 'user-id'); + }); + + test('prefers log attributes over scope attributes', () async { + fixture.scope.setAttributes({ + 'overridden': SentryAttribute.string('scope-value'), + 'kept': SentryAttribute.bool(true), + }); + + final log = givenLog() + ..attributes['overridden'] = SentryAttribute.string('log-value') + ..attributes['logOnly'] = SentryAttribute.double(1.23); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + final attributes = log.attributes; + expect(attributes['overridden']?.value, 'log-value'); + expect(attributes['kept']?.value, true); + expect(attributes['logOnly']?.type, 'double'); + }); + + test('dispatches OnProcessLog after scope merge but before beforeSendLog', + () async { + final operations = []; + bool hasScopeAttrInCallback = false; + + fixture.scope.setAttributes({ + 'scope-attr': SentryAttribute.string('scope-value'), + }); + + fixture.options.lifecycleRegistry + .registerCallback((event) { + operations.add('onProcessLog'); + hasScopeAttrInCallback = + event.log.attributes.containsKey('scope-attr'); + }); + + fixture.options.beforeSendLog = (log) { + operations.add('beforeSendLog'); + return log; + }; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(operations, ['onProcessLog', 'beforeSendLog']); + expect(hasScopeAttrInCallback, isTrue); + }); + + test('keeps attributes added by lifecycle callbacks', () async { + fixture.options.lifecycleRegistry + .registerCallback((event) { + event.log.attributes['callback-key'] = + SentryAttribute.string('callback-value'); + event.log.attributes[SemanticAttributesConstants.sentryEnvironment] = + SentryAttribute.string('callback-env'); + }); + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + final attributes = log.attributes; + expect(attributes['callback-key']?.value, 'callback-value'); + expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, + 'callback-env'); + }); + + test('does not add user attributes when sendDefaultPii is false', + () async { + fixture.options.sendDefaultPii = false; + await fixture.scope.setUser(SentryUser(id: 'user-id')); + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect( + log.attributes.containsKey(SemanticAttributesConstants.userId), + isFalse, + ); + }); + }); + + group('when logs are disabled', () { + test('does not add logs to processor', () async { + fixture.options.enableLogs = false; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs, isEmpty); + }); + }); + + group('when beforeSendLog is configured', () { + test('returning null drops the log', () async { + fixture.options.beforeSendLog = (_) => null; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs, isEmpty); + }); + + test('returning null records lost event in client report', () async { + fixture.options.beforeSendLog = (_) => null; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.recorder.discardedEvents.length, 1); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.beforeSend); + expect(fixture.recorder.discardedEvents.first.category, + DataCategory.logItem); + }); + + test('can mutate the log', () async { + fixture.options.beforeSendLog = (log) { + log.body = 'modified-body'; + log.attributes['added-key'] = SentryAttribute.string('added'); + return log; + }; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs.length, 1); + final captured = fixture.processor.addedLogs.first; + expect(captured.body, 'modified-body'); + expect(captured.attributes['added-key']?.value, 'added'); + }); + + test('async callback is awaited', () async { + fixture.options.beforeSendLog = (log) async { + await Future.delayed(Duration(milliseconds: 10)); + log.body = 'async-modified'; + return log; + }; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs.length, 1); + final captured = fixture.processor.addedLogs.first; + expect(captured.body, 'async-modified'); + }); + + test('exception in callback is caught and log is still captured', + () async { + fixture.options.automatedTestMode = false; + fixture.options.beforeSendLog = (log) { + throw Exception('test'); + }; + + final log = givenLog(); + + await fixture.pipeline.captureLog(log, scope: fixture.scope); + + expect(fixture.processor.addedLogs.length, 1); + final captured = fixture.processor.addedLogs.first; + expect(captured.body, 'test'); + }); + }); + }); +} + +class Fixture { + final options = defaultTestOptions() + ..environment = 'test-env' + ..release = 'test-release' + ..sendDefaultPii = true + ..enableLogs = true; + + final processor = MockTelemetryProcessor(); + final recorder = MockClientReportRecorder(); + + late final Scope scope; + late final LogCapturePipeline pipeline; + + Fixture() { + options.telemetryProcessor = processor; + options.recorder = recorder; + scope = Scope(options); + pipeline = LogCapturePipeline(options); + } +} diff --git a/packages/dart/test/protocol/sentry_log_level_test.dart b/packages/dart/test/telemetry/log/log_level_test.dart similarity index 94% rename from packages/dart/test/protocol/sentry_log_level_test.dart rename to packages/dart/test/telemetry/log/log_level_test.dart index 8139859c0e..4ee72df62d 100644 --- a/packages/dart/test/protocol/sentry_log_level_test.dart +++ b/packages/dart/test/telemetry/log/log_level_test.dart @@ -1,5 +1,5 @@ import 'package:test/test.dart'; -import 'package:sentry/src/protocol/sentry_log_level.dart'; +import 'package:sentry/src/telemetry/log/log_level.dart'; import 'package:sentry/src/protocol/sentry_level.dart'; void main() { diff --git a/packages/dart/test/protocol/sentry_log_test.dart b/packages/dart/test/telemetry/log/log_test.dart similarity index 95% rename from packages/dart/test/protocol/sentry_log_test.dart rename to packages/dart/test/telemetry/log/log_test.dart index b138e5340a..b3f08521b5 100644 --- a/packages/dart/test/protocol/sentry_log_test.dart +++ b/packages/dart/test/telemetry/log/log_test.dart @@ -5,10 +5,12 @@ void main() { test('$SentryLog to json', () { final timestamp = DateTime.now(); final traceId = SentryId.newId(); + final spanId = SpanId.newId(); final logItem = SentryLog( timestamp: timestamp, traceId: traceId, + spanId: spanId, level: SentryLogLevel.info, body: 'fixture-body', attributes: { @@ -25,6 +27,7 @@ void main() { expect(json, { 'timestamp': timestamp.toIso8601String(), 'trace_id': traceId.toString(), + 'span_id': spanId.toString(), 'level': 'info', 'body': 'fixture-body', 'attributes': { diff --git a/packages/dart/test/telemetry/log/logger_formatter_test.dart b/packages/dart/test/telemetry/log/logger_formatter_test.dart new file mode 100644 index 0000000000..3c74f2385d --- /dev/null +++ b/packages/dart/test/telemetry/log/logger_formatter_test.dart @@ -0,0 +1,295 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/log/default_logger.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + group('$_DefaultSentryLoggerFormatter', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + void verifyPassedAttributes(Map attributes) { + expect(attributes['foo']?.type, 'string'); + expect(attributes['foo']?.value, 'bar'); + } + + void verifyBasicTemplate(SentryLog log) { + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template']?.type, 'string'); + expect(log.attributes['sentry.message.template']?.value, 'Hello, %s!'); + expect(log.attributes['sentry.message.parameter.0']?.type, 'string'); + expect(log.attributes['sentry.message.parameter.0']?.value, 'World'); + verifyPassedAttributes(log.attributes); + } + + void verifyTemplateWithMultipleArguments(SentryLog log) { + expect(log.body, 'Name: Alice, Age: 30, Active: true, Score: 95.5'); + expect(log.attributes['sentry.message.template']?.type, 'string'); + expect(log.attributes['sentry.message.template']?.value, + 'Name: %s, Age: %s, Active: %s, Score: %s'); + expect(log.attributes['sentry.message.parameter.0']?.type, 'string'); + expect(log.attributes['sentry.message.parameter.0']?.value, 'Alice'); + expect(log.attributes['sentry.message.parameter.1']?.type, 'integer'); + expect(log.attributes['sentry.message.parameter.1']?.value, 30); + expect(log.attributes['sentry.message.parameter.2']?.type, 'boolean'); + expect(log.attributes['sentry.message.parameter.2']?.value, true); + expect(log.attributes['sentry.message.parameter.3']?.type, 'double'); + expect(log.attributes['sentry.message.parameter.3']?.value, 95.5); + verifyPassedAttributes(log.attributes); + } + + group('format basic template', () { + test('for trace', () async { + await fixture.logger.fmt.trace( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + + test('for debug', () async { + await fixture.logger.fmt.debug( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + + test('for info', () async { + await fixture.logger.fmt.info( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + + test('for warn', () async { + await fixture.logger.fmt.warn( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + + test('for error', () async { + await fixture.logger.fmt.error( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + + test('for fatal', () async { + await fixture.logger.fmt.fatal( + "Hello, %s!", + ["World"], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyBasicTemplate(fixture.capturedLogs[0]); + }); + }); + + group('template with multiple arguments', () { + test('for trace', () async { + await fixture.logger.fmt.trace( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + + test('for debug', () async { + await fixture.logger.fmt.debug( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + + test('for info', () async { + await fixture.logger.fmt.info( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + + test('for warn', () async { + await fixture.logger.fmt.warn( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + + test('for error', () async { + await fixture.logger.fmt.error( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + + test('for fatal', () async { + await fixture.logger.fmt.fatal( + "Name: %s, Age: %s, Active: %s, Score: %s", + ['Alice', 30, true, 95.5], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + verifyTemplateWithMultipleArguments(fixture.capturedLogs[0]); + }); + }); + + group('template with no arguments', () { + test('for trace', () async { + await fixture.logger.fmt.trace( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + + test('for debug', () async { + await fixture.logger.fmt.debug( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + + test('for info', () async { + await fixture.logger.fmt.info( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + + test('for warn', () async { + await fixture.logger.fmt.warn( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + + test('for error', () async { + await fixture.logger.fmt.error( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + + test('for fatal', () async { + await fixture.logger.fmt.fatal( + "Hello, World!", + [], + attributes: {'foo': SentryAttribute.string('bar')}, + ); + + expect(fixture.capturedLogs.length, 1); + final log = fixture.capturedLogs[0]; + expect(log.body, 'Hello, World!'); + expect(log.attributes['sentry.message.template'], isNull); + expect(log.attributes['sentry.message.parameter.0'], isNull); + verifyPassedAttributes(log.attributes); + }); + }); + }); +} + +// Used to reference the private class in the group name +// ignore: camel_case_types +class _DefaultSentryLoggerFormatter {} + +class Fixture { + final capturedLogs = []; + final options = defaultTestOptions(); + late final SentryLogger logger; + late final Scope scope; + + Fixture() { + scope = Scope(options); + logger = DefaultSentryLogger( + captureLogCallback: (log, {scope}) { + capturedLogs.add(log); + }, + clockProvider: () => DateTime.now(), + scopeProvider: () => scope, + ); + } +} diff --git a/packages/dart/test/telemetry/log/logger_setup_integration_test.dart b/packages/dart/test/telemetry/log/logger_setup_integration_test.dart new file mode 100644 index 0000000000..24ef14af52 --- /dev/null +++ b/packages/dart/test/telemetry/log/logger_setup_integration_test.dart @@ -0,0 +1,168 @@ +import 'dart:async'; + +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/log/default_logger.dart'; +import 'package:sentry/src/telemetry/log/logger_setup_integration.dart'; +import 'package:sentry/src/telemetry/log/noop_logger.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + group('$LoggerSetupIntegration', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + group('when logs are enabled', () { + test('configures DefaultSentryLogger', () { + fixture.options.enableLogs = true; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.logger, isA()); + }); + + test('adds integration to SDK', () { + fixture.options.enableLogs = true; + + fixture.sut.call(fixture.hub, fixture.options); + + expect( + fixture.options.sdk.integrations, + contains(LoggerSetupIntegration.integrationName), + ); + }); + + test('does not override existing non-noop logger', () { + fixture.options.enableLogs = true; + final customLogger = _CustomSentryLogger(); + fixture.options.logger = customLogger; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.logger, same(customLogger)); + }); + }); + + group('when logs are disabled', () { + test('does not configure logger', () { + fixture.options.enableLogs = false; + + fixture.sut.call(fixture.hub, fixture.options); + + expect(fixture.options.logger, isA()); + }); + + test('does not add integration to SDK', () { + fixture.options.enableLogs = false; + + fixture.sut.call(fixture.hub, fixture.options); + + expect( + fixture.options.sdk.integrations, + isNot(contains(LoggerSetupIntegration.integrationName)), + ); + }); + }); + }); +} + +class Fixture { + final options = defaultTestOptions(); + + late final Hub hub; + late final LoggerSetupIntegration sut; + + Fixture() { + hub = Hub(options); + sut = LoggerSetupIntegration(); + } +} + +class _CustomSentryLogger implements SentryLogger { + @override + FutureOr trace( + String body, { + Map? attributes, + }) {} + + @override + FutureOr debug( + String body, { + Map? attributes, + }) {} + + @override + FutureOr info( + String body, { + Map? attributes, + }) {} + + @override + FutureOr warn( + String body, { + Map? attributes, + }) {} + + @override + FutureOr error( + String body, { + Map? attributes, + }) {} + + @override + FutureOr fatal( + String body, { + Map? attributes, + }) {} + + @override + SentryLoggerFormatter get fmt => _CustomSentryLoggerFormatter(); +} + +class _CustomSentryLoggerFormatter implements SentryLoggerFormatter { + @override + FutureOr trace( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr debug( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr info( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr warn( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr error( + String templateBody, + List arguments, { + Map? attributes, + }) {} + + @override + FutureOr fatal( + String templateBody, + List arguments, { + Map? attributes, + }) {} +} diff --git a/packages/dart/test/telemetry/log/logger_test.dart b/packages/dart/test/telemetry/log/logger_test.dart new file mode 100644 index 0000000000..ffb37a0530 --- /dev/null +++ b/packages/dart/test/telemetry/log/logger_test.dart @@ -0,0 +1,178 @@ +import 'package:sentry/sentry.dart'; +import 'package:sentry/src/telemetry/log/default_logger.dart'; +import 'package:test/test.dart'; + +import '../../test_utils.dart'; + +void main() { + group('$DefaultSentryLogger', () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + void verifyCaptureLog(SentryLogLevel level) { + expect(fixture.capturedLogs.length, 1); + final capturedLog = fixture.capturedLogs[0]; + + expect(capturedLog.level, level); + expect(capturedLog.body, 'test'); + // The attributes might have additional trace context, so check key attributes + expect(capturedLog.attributes['string']?.value, 'string'); + } + + test('info', () async { + final logger = fixture.getSut(); + + await logger.info('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.info); + }); + + test('trace', () async { + final logger = fixture.getSut(); + + await logger.trace('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.trace); + }); + + test('debug', () async { + final logger = fixture.getSut(); + + await logger.debug('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.debug); + }); + + test('warn', () async { + final logger = fixture.getSut(); + + await logger.warn('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.warn); + }); + + test('error', () async { + final logger = fixture.getSut(); + + await logger.error('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.error); + }); + + test('fatal', () async { + final logger = fixture.getSut(); + + await logger.fatal('test', attributes: fixture.attributes); + + verifyCaptureLog(SentryLogLevel.fatal); + }); + + // This is mostly an edge case but let's cover it just in case + test('per-log attributes override fmt template attributes on same key', + () async { + final logger = fixture.getSut(); + + await logger.fmt.info( + 'Hello, %s!', + ['World'], + attributes: { + 'sentry.message.template': SentryAttribute.string('OVERRIDE'), + 'sentry.message.parameter.0': SentryAttribute.string('Earth'), + }, + ); + + final attrs = fixture.capturedLogs[0].attributes; + expect(attrs['sentry.message.template']?.value, 'OVERRIDE'); + expect(attrs['sentry.message.parameter.0']?.value, 'Earth'); + }); + + test('sets trace id from default scope propagation context', () async { + final logger = fixture.getSut(); + + await logger.info('test'); + + expect(fixture.capturedLogs.length, 1); + final capturedLog = fixture.capturedLogs[0]; + expect(capturedLog.traceId, fixture.scope.propagationContext.traceId); + }); + + test('sets span id when span is active on default scope', () async { + final span = _MockSpan(); + fixture.scope.span = span; + + final logger = fixture.getSut(); + + await logger.info('test'); + + expect(fixture.capturedLogs.length, 1); + final capturedLog = fixture.capturedLogs[0]; + expect(capturedLog.spanId, span.context.spanId); + }); + + test('sets timestamp from clock provider', () async { + final logger = fixture.getSut(); + + await logger.info('test'); + + expect(fixture.capturedLogs.length, 1); + final capturedLog = fixture.capturedLogs[0]; + expect(capturedLog.timestamp, fixture.timestamp); + }); + + test('includes attributes when provided', () async { + final logger = fixture.getSut(); + + await logger + .info('test', attributes: {'key': SentryAttribute.string('value')}); + + expect(fixture.capturedLogs.length, 1); + final capturedLog = fixture.capturedLogs[0]; + expect(capturedLog.attributes['key']?.value, 'value'); + }); + }); +} + +class Fixture { + final options = defaultTestOptions(); + final timestamp = DateTime.fromMicrosecondsSinceEpoch(0); + final capturedLogs = []; + late final Scope scope; + + final attributes = { + 'string': SentryAttribute.string('string'), + 'int': SentryAttribute.int(1), + 'double': SentryAttribute.double(1.23456789), + 'bool': SentryAttribute.bool(true), + 'double_int': SentryAttribute.double(1.0), + 'nan': SentryAttribute.double(double.nan), + 'positive_infinity': SentryAttribute.double(double.infinity), + 'negative_infinity': SentryAttribute.double(double.negativeInfinity), + }; + + Fixture() { + scope = Scope(options); + } + + SentryLogger getSut() { + return DefaultSentryLogger( + captureLogCallback: (log, {scope}) { + capturedLogs.add(log); + }, + clockProvider: () => timestamp, + scopeProvider: () => scope, + ); + } +} + +class _MockSpan implements ISentrySpan { + final SentrySpanContext _context = SentrySpanContext(operation: 'test'); + + @override + SentrySpanContext get context => _context; + + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} diff --git a/packages/dart/test/telemetry/processing/processor_integration_test.dart b/packages/dart/test/telemetry/processing/processor_integration_test.dart index b0a41d07f4..169ecf9f97 100644 --- a/packages/dart/test/telemetry/processing/processor_integration_test.dart +++ b/packages/dart/test/telemetry/processing/processor_integration_test.dart @@ -88,6 +88,7 @@ class _Fixture { SentryLog createLog() { return SentryLog( timestamp: DateTime.now().toUtc(), + traceId: SentryId.newId(), level: SentryLogLevel.info, body: 'test log', attributes: {}, diff --git a/packages/dart/test/telemetry/processing/processor_test.dart b/packages/dart/test/telemetry/processing/processor_test.dart index 46fefd0299..2c4914942d 100644 --- a/packages/dart/test/telemetry/processing/processor_test.dart +++ b/packages/dart/test/telemetry/processing/processor_test.dart @@ -119,6 +119,7 @@ class Fixture { SentryLog createLog({String body = 'test log'}) { return SentryLog( timestamp: DateTime.now().toUtc(), + traceId: SentryId.newId(), level: SentryLogLevel.info, body: body, attributes: {}, diff --git a/packages/flutter/lib/src/integrations/load_contexts_integration.dart b/packages/flutter/lib/src/integrations/load_contexts_integration.dart index 3d4791d5b1..b46a7a7494 100644 --- a/packages/flutter/lib/src/integrations/load_contexts_integration.dart +++ b/packages/flutter/lib/src/integrations/load_contexts_integration.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:sentry/sentry.dart'; import 'package:collection/collection.dart'; import 'package:sentry/src/event_processor/enricher/enricher_event_processor.dart'; -import 'package:sentry/src/logs_enricher_integration.dart'; import '../native/sentry_native_binding.dart'; import '../sentry_flutter_options.dart'; import '../utils/internal_logger.dart'; @@ -24,7 +23,7 @@ class LoadContextsIntegration implements Integration { final SentryNativeBinding _native; Map? _cachedAttributes; SentryFlutterOptions? _options; - SdkLifecycleCallback? _logCallback; + SdkLifecycleCallback? _logCallback; SdkLifecycleCallback? _metricCallback; LoadContextsIntegration(this._native); @@ -51,28 +50,19 @@ class LoadContextsIntegration implements Integration { options.addEventProcessor(enricherEventProcessor); } if (options.enableLogs) { - final logsEnricherIntegration = options.integrations.firstWhereOrNull( - (element) => element is LogsEnricherIntegration, - ); - if (logsEnricherIntegration != null) { - // Contexts from native cover the os.name and os.version attributes, - // so we can remove the logsEnricherIntegration. - options.removeIntegration(logsEnricherIntegration); - } - _logCallback = (event) async { try { final attributes = await _nativeContextAttributes(); event.log.attributes.addAllIfAbsent(attributes); } catch (exception, stackTrace) { internalLogger.error( - 'LoadContextsIntegration failed to load contexts for $OnBeforeCaptureLog', + 'LoadContextsIntegration failed to load contexts for $OnProcessLog', error: exception, stackTrace: stackTrace, ); } }; - options.lifecycleRegistry.registerCallback( + options.lifecycleRegistry.registerCallback( _logCallback!, ); } @@ -104,8 +94,7 @@ class LoadContextsIntegration implements Integration { if (options == null) return; if (_logCallback != null) { - options.lifecycleRegistry - .removeCallback(_logCallback!); + options.lifecycleRegistry.removeCallback(_logCallback!); _logCallback = null; } if (_metricCallback != null) { diff --git a/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart b/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart index 4883ad1bb1..7936dffde7 100644 --- a/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart +++ b/packages/flutter/lib/src/integrations/replay_telemetry_integration.dart @@ -15,7 +15,7 @@ class ReplayTelemetryIntegration implements Integration { ReplayTelemetryIntegration(this._native); SentryFlutterOptions? _options; - SdkLifecycleCallback? _onBeforeCaptureLog; + SdkLifecycleCallback? _onProcessLog; SdkLifecycleCallback? _onProcessMetric; @override @@ -28,7 +28,7 @@ class ReplayTelemetryIntegration implements Integration { _options = options; - _onBeforeCaptureLog = (OnBeforeCaptureLog event) { + _onProcessLog = (OnProcessLog event) { _addReplayAttributes( hub.scope.replayId, event.log.attributes, @@ -46,8 +46,7 @@ class ReplayTelemetryIntegration implements Integration { ); }; - options.lifecycleRegistry - .registerCallback(_onBeforeCaptureLog!); + options.lifecycleRegistry.registerCallback(_onProcessLog!); options.lifecycleRegistry .registerCallback(_onProcessMetric!); options.sdk.addIntegration(integrationName); @@ -76,13 +75,12 @@ class ReplayTelemetryIntegration implements Integration { @override Future close() async { final options = _options; - final onBeforeCaptureLog = _onBeforeCaptureLog; + final onProcessLog = _onProcessLog; final onProcessMetric = _onProcessMetric; if (options != null) { - if (onBeforeCaptureLog != null) { - options.lifecycleRegistry - .removeCallback(onBeforeCaptureLog); + if (onProcessLog != null) { + options.lifecycleRegistry.removeCallback(onProcessLog); } if (onProcessMetric != null) { options.lifecycleRegistry @@ -91,7 +89,7 @@ class ReplayTelemetryIntegration implements Integration { } _options = null; - _onBeforeCaptureLog = null; + _onProcessLog = null; _onProcessMetric = null; } } diff --git a/packages/flutter/test/integrations/load_contexts_integration_test.dart b/packages/flutter/test/integrations/load_contexts_integration_test.dart index 5c07b1648a..f74f261bad 100644 --- a/packages/flutter/test/integrations/load_contexts_integration_test.dart +++ b/packages/flutter/test/integrations/load_contexts_integration_test.dart @@ -5,7 +5,6 @@ library; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import 'package:sentry/src/logs_enricher_integration.dart'; import 'package:sentry/src/sentry_tracer.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/integrations/load_contexts_integration.dart'; @@ -689,20 +688,6 @@ void main() { expect(log.attributes['device.family']?.value, 'fixture-device-family'); }); - test('removes logsEnricherIntegration', () async { - final integration = LogsEnricherIntegration(); - fixture.options.addIntegration(integration); - - fixture.options.enableLogs = true; - await fixture.registerIntegration(); - - expect( - fixture.options.integrations - .any((element) => element is LogsEnricherIntegration), - isFalse, - ); - }); - test( 'does not add os and device attributes to log if enableLogs is false', () async { @@ -731,8 +716,8 @@ void main() { final log = givenLog(); await fixture.hub.captureLog(log); - expect(log.attributes['os.name'], isNull); - expect(log.attributes['os.version'], isNull); + // os.name and os.version are set by defaultAttributes() from Dart-level + // OS detection, not from native loadContexts(), so we only check device.* expect(log.attributes['device.brand'], isNull); expect(log.attributes['device.model'], isNull); expect(log.attributes['device.family'], isNull); @@ -816,16 +801,14 @@ void main() { await fixture.registerIntegration(); expect( - fixture - .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + fixture.options.lifecycleRegistry.lifecycleCallbacks[OnProcessLog], isNotEmpty, ); fixture.sut.close(); expect( - fixture - .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + fixture.options.lifecycleRegistry.lifecycleCallbacks[OnProcessLog], isEmpty, ); }); @@ -845,8 +828,7 @@ void main() { isEmpty, ); expect( - fixture - .options.lifecycleRegistry.lifecycleCallbacks[OnBeforeCaptureLog], + fixture.options.lifecycleRegistry.lifecycleCallbacks[OnProcessLog], isEmpty, ); }); diff --git a/packages/flutter/test/integrations/replay_telemetry_integration_test.dart b/packages/flutter/test/integrations/replay_telemetry_integration_test.dart index 460c0c0c0a..ab7d010348 100644 --- a/packages/flutter/test/integrations/replay_telemetry_integration_test.dart +++ b/packages/flutter/test/integrations/replay_telemetry_integration_test.dart @@ -194,7 +194,7 @@ class Fixture { when(hub.scope).thenReturn(scope); when(hub.captureLog(any)).thenAnswer((invocation) async { final log = invocation.positionalArguments.first as SentryLog; - await options.lifecycleRegistry.dispatchCallback(OnBeforeCaptureLog(log)); + await options.lifecycleRegistry.dispatchCallback(OnProcessLog(log)); }); when(nativeBinding.replayId).thenReturn(null); } diff --git a/packages/logging/lib/src/logging_integration.dart b/packages/logging/lib/src/logging_integration.dart index 948faf1df4..061e699c69 100644 --- a/packages/logging/lib/src/logging_integration.dart +++ b/packages/logging/lib/src/logging_integration.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:meta/meta.dart'; From 044525d03dc5209b4f56e6e8464dabe3fdf7c819 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:03:27 +0100 Subject: [PATCH 27/62] build(deps): bump actions/setup-java from 4 to 5 (#3461) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/kotlin-version-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kotlin-version-compatibility.yml b/.github/workflows/kotlin-version-compatibility.yml index be86fb1cdc..8d7669c5f9 100644 --- a/.github/workflows/kotlin-version-compatibility.yml +++ b/.github/workflows/kotlin-version-compatibility.yml @@ -40,7 +40,7 @@ jobs: - uses: actions/checkout@v5 - name: Setup Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: "temurin" java-version: "17" From bb4f1e66e9fd2796a3e367779c163aab6288297a Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Fri, 23 Jan 2026 13:05:30 +0100 Subject: [PATCH 28/62] feat(flutter): Add captureNativeFailedRequests option for iOS/macOS (#3472) Add a new `captureNativeFailedRequests` option to control native HTTP failed request capturing independently from `captureFailedRequests`. This separation allows users to: - Keep Dart-side failed request capturing enabled while disabling native - Or vice versa, based on their needs For backwards compatibility, `captureNativeFailedRequests` defaults to `null`, which falls back to the value of `captureFailedRequests`. This ensures existing users who set `captureFailedRequests = false` will still have native capturing disabled as expected. --- CHANGELOG.md | 4 + packages/dart/lib/src/sentry_options.dart | 15 +++- .../lib/src/native/sentry_native_channel.dart | 3 +- .../test/sentry_native_channel_test.dart | 80 +++++++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e8db206d..764799415a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ - `Sentry.metrics.gauge(...)` - `Sentry.metrics.count(...)` - `Sentry.metrics.distribution(...)` +- Add `captureNativeFailedRequests` option for iOS/macOS ([#3472](https://github.com/getsentry/sentry-dart/pull/3472)) + - This option allows controlling native HTTP error capturing independently from `captureFailedRequests`. + - When `null` (the default), it falls back to `captureFailedRequests` for backwards compatibility. + - Set to `false` to disable native failed request capturing while keeping Dart-side capturing enabled. ### Enhancements diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index bb1cc755b0..ffc0eeecdf 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -333,10 +333,21 @@ class SentryOptions { /// - In an browser environment this can be requests which fail because of CORS. /// - In an mobile or desktop application this can be requests which failed /// because the connection was interrupted. - /// Use with [SentryHttpClient] or `sentry_dio` integration for this to work, - /// or iOS native where it sets the value to `enableCaptureFailedRequests`. + /// Use with [SentryHttpClient] or `sentry_dio` integration for this to work + /// + /// If you wish to disable capturing native failed requests on iOS/macOS, use [captureNativeFailedRequests] instead. + // TODO(major-v10): do not sync this with native options, instead use captureNativeFailedRequests instead to sync. bool captureFailedRequests = true; + /// Whether failed HTTP requests are captured by the native iOS/macOS SDK. + /// + /// This allows controlling native-side HTTP error capturing independently + /// from [captureFailedRequests], which controls Dart-side capturing. + /// + /// When `null` (the default), falls back to [captureFailedRequests]. + // TODO(major-v10): it's currently nullable for backwards compatibility, make non-nullable by default. + bool? captureNativeFailedRequests; + /// Whether to records requests as breadcrumbs. This is on by default. /// It only has an effect when the SentryHttpClient or dio integration is in /// use, or iOS native where it sets the value to `enableNetworkBreadcrumbs`. diff --git a/packages/flutter/lib/src/native/sentry_native_channel.dart b/packages/flutter/lib/src/native/sentry_native_channel.dart index ea8ff5ecb1..10726fdc3a 100644 --- a/packages/flutter/lib/src/native/sentry_native_channel.dart +++ b/packages/flutter/lib/src/native/sentry_native_channel.dart @@ -66,7 +66,8 @@ class SentryNativeChannel 'proguardUuid': options.proguardUuid, 'maxAttachmentSize': options.maxAttachmentSize, 'recordHttpBreadcrumbs': options.recordHttpBreadcrumbs, - 'captureFailedRequests': options.captureFailedRequests, + 'captureFailedRequests': + options.captureNativeFailedRequests ?? options.captureFailedRequests, 'enableAppHangTracking': options.enableAppHangTracking, 'connectionTimeoutMillis': options.connectionTimeout.inMilliseconds, 'readTimeoutMillis': options.readTimeout.inMilliseconds, diff --git a/packages/flutter/test/sentry_native_channel_test.dart b/packages/flutter/test/sentry_native_channel_test.dart index 3d2a590ea1..98bcd21563 100644 --- a/packages/flutter/test/sentry_native_channel_test.dart +++ b/packages/flutter/test/sentry_native_channel_test.dart @@ -502,6 +502,86 @@ void main() { }); }); } + + group('init captureFailedRequests on iOS/macOS', () { + late SentryNativeBinding sut; + late MockMethodChannel channel; + + Future> callInitAndCaptureArgs( + SentryFlutterOptions options) async { + when(channel.invokeMethod('initNativeSdk', any)) + .thenAnswer((_) => Future.value()); + + await sut.init(MockHub()); + + final captured = + verify(channel.invokeMethod('initNativeSdk', captureAny)).captured; + return captured.first as Map; + } + + setUp(() { + channel = MockMethodChannel(); + }); + + test( + 'uses captureFailedRequests when captureNativeFailedRequests is null (backwards compatibility)', + () async { + final options = defaultTestOptions() + ..platform = MockPlatform.iOS() + ..methodChannel = channel + ..captureFailedRequests = false + ..captureNativeFailedRequests = null; + sut = createBinding(options); + + final args = await callInitAndCaptureArgs(options); + + expect(args['captureFailedRequests'], false); + }); + + test( + 'uses captureNativeFailedRequests when explicitly set to true even if captureFailedRequests is false', + () async { + final options = defaultTestOptions() + ..platform = MockPlatform.iOS() + ..methodChannel = channel + ..captureFailedRequests = false + ..captureNativeFailedRequests = true; + sut = createBinding(options); + + final args = await callInitAndCaptureArgs(options); + + expect(args['captureFailedRequests'], true); + }); + + test( + 'uses captureNativeFailedRequests when explicitly set to false even if captureFailedRequests is true', + () async { + final options = defaultTestOptions() + ..platform = MockPlatform.iOS() + ..methodChannel = channel + ..captureFailedRequests = true + ..captureNativeFailedRequests = false; + sut = createBinding(options); + + final args = await callInitAndCaptureArgs(options); + + expect(args['captureFailedRequests'], false); + }); + + test('defaults to captureFailedRequests value when both use defaults', + () async { + final options = defaultTestOptions() + ..platform = MockPlatform.iOS() + ..methodChannel = channel; + // captureFailedRequests defaults to true + // captureNativeFailedRequests defaults to null + sut = createBinding(options); + + final args = await callInitAndCaptureArgs(options); + + expect(args['captureFailedRequests'], true); + }); + }); } /// Returns a matcher for the android-specific failures we expect when native From 20442931a924567d251d5d5319b24fae2ba0445c Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Fri, 23 Jan 2026 12:19:03 +0000 Subject: [PATCH 29/62] release: 9.11.0-beta.1 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 764799415a..d33853d096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.11.0-beta.1 ### Features diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index aa560c82ed..0fc0e0e3c6 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.11.0-beta.1 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.10.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.9.2 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | | 9.9.1 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index e588e30755..4c7193efbd 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index f0c652d72a..4501f87fc6 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.10.0 +version: 9.11.0-beta.1 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index 462649248d..d4125dcb5a 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index ad1f86fe57..d1bb7792d7 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.10.0 + sentry: 9.11.0-beta.1 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index a06123883a..0c42c42ca2 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 183f5a0da0..5b91abe4b6 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.10.0 + sentry: 9.11.0-beta.1 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 9347900f4d..ca7499e2e2 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index f8c09eb8b3..da9541e593 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.10.0 + sentry: 9.11.0-beta.1 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index e052966065..6858109abf 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.10.0 + sentry: 9.11.0-beta.1 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index 7763ceb785..76a21abe17 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.10.0 +version: 9.11.0-beta.1 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 184306e03b..c6d17f4ee3 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 655ba9030d..22d7e1c19e 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.10.0 +version: 9.11.0-beta.1 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.10.0 + sentry: 9.11.0-beta.1 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index f307eda4fe..9f9dc73438 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index 4047717c39..71a180ad82 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.10.0 + sentry: 9.11.0-beta.1 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index 3536b493e2..ec079e8858 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index a1d7b9fe3c..0089b1bd30 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.10.0 + sentry: 9.11.0-beta.1 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index 4d3ecff900..f12f83d190 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.10.0 + sentry: 9.11.0-beta.1 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index e4669cc52b..9893784ca3 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index 534a03de2b..860320d7b9 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.10.0 + sentry: 9.11.0-beta.1 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index 5c40e70bf3..578b349e1b 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.10.0'; +const String sdkVersion = '9.11.0-beta.1'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index 8fe449b308..77fe131751 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.10.0 + sentry: 9.11.0-beta.1 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 44db042557..076a4ab71f 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.10.0 +version: 9.11.0-beta.1 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -10,7 +10,7 @@ environment: dependencies: http: ^1.3.0 - sentry: 9.10.0 + sentry: 9.11.0-beta.1 dev_dependencies: supabase: ^2.6.0 From 388c7e1ac96276bc2366811358a45ee96f87fadd Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Fri, 23 Jan 2026 17:56:14 +0100 Subject: [PATCH 30/62] chore: update GitHub Actions workflows to use updater v3 (#3468) * chore: update GitHub Actions workflows to use new updater version Refactor the update-deps.yml workflow to utilize the latest version of the updater action, improving the structure and permissions for dependency updates across Android, Cocoa, JavaScript, Native, and Symbol Collector jobs. * chore: add pull request trigger for update-deps.yml workflow Include a pull request trigger in the update-deps.yml workflow for testing purposes, while maintaining existing push configurations. * chore: update update-deps.yml to use ssh-key instead of api-token Refactor the update-deps.yml workflow to replace the api-token with ssh-key for Android, Cocoa, JavaScript, Native, and Symbol Collector jobs, enhancing security and access management. * Update * Fix cocoa * Fix formatting in update-deps.yml permissions section * Modify update-deps workflow triggers Removed pull_request trigger from update-deps workflow. * Fix cocoa * Update * Update --- .github/workflows/update-deps.yml | 92 +++++++++++++++++-------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/.github/workflows/update-deps.yml b/.github/workflows/update-deps.yml index 8d9e2122ff..82675c6ff2 100644 --- a/.github/workflows/update-deps.yml +++ b/.github/workflows/update-deps.yml @@ -4,61 +4,69 @@ on: # Run every day. schedule: - cron: "0 3 * * *" - # And on on every PR merge so we get the updated dependencies ASAP, and to make sure the changelog doesn't conflict. + # And on every PR merge so we get the updated dependencies ASAP, and to make sure the changelog doesn't conflict. push: branches: - main +permissions: + contents: write + pull-requests: write + actions: write + jobs: android: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: packages/flutter/scripts/update-android.sh - name: Android SDK - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: packages/flutter/scripts/update-android.sh + name: Android SDK + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} cocoa: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: packages/flutter/scripts/update-cocoa.sh - name: Cocoa SDK - runs-on: macos-latest - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: macos-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: packages/flutter/scripts/update-cocoa.sh + name: Cocoa SDK + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} js: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: packages/flutter/scripts/update-js.sh - name: JavaScript SDK - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: packages/flutter/scripts/update-js.sh + name: JavaScript SDK + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} native: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: packages/flutter/scripts/update-native.sh - name: Native SDK - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: packages/flutter/scripts/update-native.sh + name: Native SDK + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} metrics-flutter: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: metrics/flutter.properties - name: Flutter SDK (metrics) - changelog-entry: false - pr-strategy: update - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: metrics/flutter.properties + name: Flutter SDK Metrics + changelog-entry: false + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} symbol-collector: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 - with: - path: scripts/update-symbol-collector.sh - name: Symbol collector CLI - changelog-entry: false - pr-strategy: update - secrets: - api-token: ${{ secrets.CI_DEPLOY_KEY }} + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/updater@v3 + with: + path: scripts/update-symbol-collector.sh + name: Symbol Collector CLI + changelog-entry: false + ssh-key: ${{ secrets.CI_DEPLOY_KEY }} From 6e0abbc38df090a6b77f949bb29fc2fdb36a2c38 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 26 Jan 2026 11:42:06 +0100 Subject: [PATCH 31/62] Disable wasm runner for now (#3478) --- .github/workflows/flutter.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 49210e7d1b..99cafa26dd 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -43,14 +43,10 @@ jobs: os: windows - target: js os: ubuntu - - target: wasm - os: ubuntu exclude: - # Flutter WASM tests don't compile on beta currently. - # We can re-enable when it is fixed by Flutter. - # https://github.com/getsentry/sentry-dart/pull/3003 + # Flutter WASM tests don't compile on beta currently and hangs on stable. + # https://github.com/getsentry/sentry-dart/issues/3477 - target: wasm - sdk: beta steps: - uses: actions/checkout@v6 From dd9cba6b47e0e1597982a661d7c2d9aa83cbbe42 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Mon, 26 Jan 2026 12:09:15 +0100 Subject: [PATCH 32/62] ci(testflight): Update to Xcode 26.2 (#3479) Co-authored-by: Claude Opus 4.5 --- .github/workflows/testflight.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 32ccb3dceb..8d058aea95 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - - run: xcodes select 16.4 + - run: xcodes select 26.2 - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 with: ruby-version: '2.7.5' From 6275fbd8e5717a2975e7309c8b11865c75ef4a17 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 29 Jan 2026 14:17:42 +0100 Subject: [PATCH 33/62] ref(dart): Remove unused beforeMetricCallback (#3484) Remove dead code that was never used in the codebase. The BeforeMetricCallback typedef and beforeMetricCallback field in SentryOptions had no references anywhere in the SDK. Co-authored-by: Claude --- CHANGELOG.md | 6 ++++++ packages/dart/lib/src/sentry_options.dart | 11 ----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d33853d096..0bc4701040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Internals + +- Remove deprecated `beforeMetricCallback` from options ([#3484](https://github.com/getsentry/sentry-dart/pull/3450)) + ## 9.11.0-beta.1 ### Features diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index ffc0eeecdf..99e861aabc 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -211,10 +211,6 @@ class SentryOptions { /// to the scope. When nothing is returned from the function, the breadcrumb is dropped BeforeBreadcrumbCallback? beforeBreadcrumb; - /// This function is called right before a metric is about to be emitted. - /// Can return true to emit the metric, or false to drop it. - BeforeMetricCallback? beforeMetricCallback; - /// This function is called right before a log is about to be sent. /// Can return a modified log or null to drop the log. BeforeSendLogCallback? beforeSendLog; @@ -703,13 +699,6 @@ typedef BeforeBreadcrumbCallback = Breadcrumb? Function( Hint hint, ); -/// This function is called right before a metric is about to be emitted. -/// Can return true to emit the metric, or false to drop it. -typedef BeforeMetricCallback = bool Function( - String key, { - Map? tags, -}); - /// This function is called right before a log is about to be sent. /// Can return a modified log or null to drop the log. typedef BeforeSendLogCallback = FutureOr Function(SentryLog log); From a2c8611f76c62bb89dee0ffed698e095caa840b4 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 29 Jan 2026 14:40:28 +0100 Subject: [PATCH 34/62] ref(tracing-instrumentation): Introduce internal instrumentation abstraction for packages (#3488) * feat(tracing): Introduce internal instrumentation API for Sentry - Added `InstrumentationSpan` and `LegacyInstrumentationSpan` classes to provide a backend-agnostic abstraction for tracing. - Implemented `InstrumentationSpanFactory` for creating spans, allowing for future flexibility in span implementations. - Enhanced `SentryOptions` to include a `spanFactory` for custom span creation. - Updated various components to utilize the new instrumentation API, including `SentryInstrumentation` and `TransactionInstrumentation`. - Refactored existing database executor and batch classes to support the new instrumentation spans. This update improves the tracing capabilities and prepares the codebase for future enhancements in span management. * refactor(tracing): Simplify transaction instrumentation documentation - Removed outdated comments and example usage from the `TransactionInstrumentation` class. - Clarified the behavior of transaction methods by streamlining the documentation. - Enhanced code readability and maintainability by focusing on essential information. This update improves the clarity of the transaction instrumentation API, making it easier for developers to understand its usage. * Update * Update * Update * Update * Update * refactor(tracing): Improve transaction stack management in Sentry instrumentation - Ensured that the transaction stack maintains nesting invariants by always pushing a null value when no parent exists. - Simplified the logic for adding and removing spans from the stack, enhancing clarity and reducing potential errors. - Removed redundant comments and streamlined the handling of null spans in transaction methods. This update enhances the robustness of the Sentry tracing implementation, making it more reliable during transaction execution. * Remove unnecessary hint * Fix review issues * Fix review issues * Fix review issues * Fix review issues * Remove unnecessary files * Naming * Naming * Analyzer * Naming * Add test * Update * Change finish call to unawaited in error handling * Add async import to sentry_span_helper.dart * Update * ref(tracing-instrumentation): migrate hive, isar, file, supabase and link (#3489) * feat(hive): add internal logger for sentry_hive package Co-Authored-By: Claude Opus 4.5 * feat(hive): migrate SentrySpanHelper to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Add proper null checks with warning logs - Maintain both async and sync wrapper methods Co-Authored-By: Claude Opus 4.5 * feat(hive): update classes to use new SentrySpanHelper constructor - Pass Hub directly to SentrySpanHelper constructor - Remove setHub() method calls - Update tests to use constructor parameter Co-Authored-By: Claude Opus 4.5 * feat(file): migrate to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Maintain both async and sync wrapper methods Co-Authored-By: Claude Opus 4.5 * feat(supabase): migrate to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Return InstrumentationSpan from _createSpan helper Co-Authored-By: Claude Opus 4.5 * feat(link): migrate SentryTracingLink to InstrumentationSpan - Use InstrumentationSpanFactory for child span creation - Keep legacy API for transaction creation (when shouldStartTransaction=true) - Wrap transactions in LegacyInstrumentationSpan for unified interface Co-Authored-By: Claude Opus 4.5 * feat(link): migrate SentryRequestSerializer to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() Co-Authored-By: Claude Opus 4.5 * feat(link): migrate SentryResponseParser to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() Co-Authored-By: Claude Opus 4.5 * Update * Update * Update * Update * Update * Update * feat(supabase): add internal logger and update dependencies - Introduced an internal logger using Sentry for better tracing. - Added 'meta' package as a dependency in pubspec.yaml. - Updated Sentry tracing logic to utilize the new internal logger for warnings. * Update --------- Co-authored-by: Claude Opus 4.5 * ref(dart): instrumentation span for http dio (#3493) * ref(tracing-instrumentation): migrate http and dio to instrumentation span Migrate TracingClient (http package) and TracingClientAdapter (dio package) to use the new InstrumentationSpanFactory pattern, consistent with the recent migration of hive, isar, file, supabase, and link packages. Changes: - Add InstrumentationSpanFactory field to TracingClient and TracingClientAdapter - Replace hub.getSpan()?.startChild() with spanFactory.getSpan()/createSpan() - Extract underlying ISentrySpan via LegacyInstrumentationSpan.spanReference for tracing headers (sentry-trace, baggage, traceparent) - Add applyToInstrumentationSpan() method to UrlDetails for URL data All existing tests pass without modification, preserving backward compatibility. Co-Authored-By: Claude Opus 4.5 * ref(dio): migrate SentryTransformer to instrumentation span Complete the migration of dio package to use InstrumentationSpanFactory by updating SentryTransformer's transformRequest and transformResponse methods. Co-Authored-By: Claude Opus 4.5 * ref(tracing): rename applyToInstrumentationSpan to applyToSpan Remove the old ISentrySpan-based applyToSpan method and rename applyToInstrumentationSpan to applyToSpan since all callers now use InstrumentationSpan. Update url_details_test.dart to use MockInstrumentationSpan. Co-Authored-By: Claude Opus 4.5 * chore(tests): add mock_span import to lifecycle tests Added the mock_span import to both sentry_client_lifecycle_test.dart and sentry_client_sdk_lifecycle_test.dart to facilitate testing with spans. * feat(tests): add MockSpan class for testing Sentry spans Introduced a new MockSpan class in mock_span.dart to facilitate testing with SentrySpan, providing a mock implementation for use in unit tests. * ref(tracing): remove commented code for extracting ISentrySpan Removed commented-out code related to extracting ISentrySpan for tracing headers in TracingClient and TracingClientAdapter, streamlining the codebase. * ref(tracing): enhance tracing header handling with InstrumentationSpan Updated TracingClient and TracingClientAdapter to utilize the new addTracingHeadersFromInstrumentationSpan method for adding tracing headers. This change simplifies the code by directly passing the InstrumentationSpan, improving clarity and maintainability. Additionally, new methods for converting spans to Sentry trace and baggage headers were added to the InstrumentationSpan interface. * ref(tracing): rename addTracingHeadersFromInstrumentationSpan to addTracingHeadersToHttpHeader Updated the TracingClient and TracingClientAdapter to use the renamed addTracingHeadersToHttpHeader method for adding tracing headers. This change improves code clarity and consistency across the codebase by standardizing the method name. Adjusted related tests to accommodate the new method signature. * ref(baggage): remove logging callback from SentryBaggage Refactored SentryBaggage to eliminate the logging callback, replacing it with an internal logger for improved logging consistency. Updated related methods and tests to reflect this change, enhancing code clarity and maintainability. * Update * ref(baggage): simplify toBaggage method by removing logging callback Refactored the toBaggage method in SentryTraceContextHeader to eliminate the logging callback, enhancing code clarity. Updated the SentryTracer to reflect this change, ensuring consistency across the codebase. * Update --------- Co-authored-by: Claude Opus 4.5 * Update CHANGELOG --------- Co-authored-by: Claude Opus 4.5 --- CHANGELOG.md | 1 + packages/dart/lib/sentry.dart | 2 + .../lib/src/http_client/tracing_client.dart | 40 +++++---- packages/dart/lib/src/sentry_baggage.dart | 52 ++++------- packages/dart/lib/src/sentry_client.dart | 5 +- packages/dart/lib/src/sentry_options.dart | 9 ++ .../lib/src/sentry_trace_context_header.dart | 7 +- packages/dart/lib/src/sentry_tracer.dart | 2 +- .../instrumentation/instrumentation.dart | 5 ++ .../instrumentation/instrumentation_span.dart | 68 +++++++++++++++ .../tracing/instrumentation/span_factory.dart | 55 ++++++++++++ .../dart/lib/src/utils/tracing_utils.dart | 39 ++++----- packages/dart/lib/src/utils/url_details.dart | 2 +- packages/dart/test/mocks/mock_span.dart | 8 ++ .../test/sentry_client_lifecycle_test.dart | 2 +- .../sentry_client_sdk_lifecycle_test.dart | 2 +- .../dart/test/utils/tracing_utils_test.dart | 16 ++-- .../dart/test/utils/url_details_test.dart | 14 ++- packages/dio/lib/src/sentry_transformer.dart | 31 ++++--- .../dio/lib/src/tracing_client_adapter.dart | 43 ++++++---- packages/drift/lib/src/constants.dart | 1 - packages/drift/lib/src/internal_logger.dart | 5 ++ .../drift/lib/src/sentry_span_helper.dart | 73 +++++++++------- packages/drift/test/sentry_drift_test.dart | 81 +++++++++++++++++ packages/file/lib/src/sentry_file.dart | 20 +++-- packages/hive/lib/src/sentry_box.dart | 11 +-- packages/hive/lib/src/sentry_box_base.dart | 11 +-- .../hive/lib/src/sentry_box_collection.dart | 27 +++--- packages/hive/lib/src/sentry_hive_impl.dart | 21 +++-- packages/hive/lib/src/sentry_lazy_box.dart | 11 +-- packages/hive/lib/src/sentry_span_helper.dart | 82 +++++++----------- .../hive/test/sentry_box_collection_test.dart | 4 +- packages/isar/lib/src/internal_logger.dart | 5 ++ packages/isar/lib/src/sentry_isar.dart | 19 ++-- .../isar/lib/src/sentry_isar_collection.dart | 12 +-- packages/isar/lib/src/sentry_span_helper.dart | 86 ++++++++----------- .../lib/src/sentry_request_serializer.dart | 18 ++-- .../link/lib/src/sentry_response_parser.dart | 20 +++-- .../link/lib/src/sentry_tracing_link.dart | 35 +++++--- packages/sqflite/lib/src/sentry_batch.dart | 18 ++-- packages/sqflite/lib/src/sentry_database.dart | 20 +++-- .../lib/src/sentry_database_executor.dart | 76 ++++++++++------ packages/sqflite/lib/src/sentry_sqflite.dart | 7 +- .../src/sentry_sqflite_database_factory.dart | 13 ++- .../sentry_database_span_attributes.dart | 9 +- .../supabase/lib/src/internal_logger.dart | 5 ++ .../src/sentry_supabase_tracing_client.dart | 27 +++--- packages/supabase/pubspec.yaml | 1 + 48 files changed, 719 insertions(+), 402 deletions(-) create mode 100644 packages/dart/lib/src/tracing/instrumentation/instrumentation.dart create mode 100644 packages/dart/lib/src/tracing/instrumentation/instrumentation_span.dart create mode 100644 packages/dart/lib/src/tracing/instrumentation/span_factory.dart create mode 100644 packages/dart/test/mocks/mock_span.dart create mode 100644 packages/drift/lib/src/internal_logger.dart create mode 100644 packages/isar/lib/src/internal_logger.dart create mode 100644 packages/supabase/lib/src/internal_logger.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bc4701040..b545eb0d12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Internals - Remove deprecated `beforeMetricCallback` from options ([#3484](https://github.com/getsentry/sentry-dart/pull/3450)) +- Add span factory to allow swappable span backends in integrations ([#3488](https://github.com/getsentry/sentry-dart/pull/3450)) ## 9.11.0-beta.1 diff --git a/packages/dart/lib/sentry.dart b/packages/dart/lib/sentry.dart index 76177fb4e9..425e4cb01f 100644 --- a/packages/dart/lib/sentry.dart +++ b/packages/dart/lib/sentry.dart @@ -47,6 +47,8 @@ export 'src/span_data_convention.dart'; export 'src/spotlight.dart'; export 'src/throwable_mechanism.dart'; export 'src/tracing.dart'; +// ignore: invalid_export_of_internal_element +export 'src/tracing/instrumentation/instrumentation.dart'; export 'src/transport/transport.dart'; export 'src/type_check_hint.dart'; // ignore: invalid_export_of_internal_element diff --git a/packages/dart/lib/src/http_client/tracing_client.dart b/packages/dart/lib/src/http_client/tracing_client.dart index 8086d13a16..5133641b10 100644 --- a/packages/dart/lib/src/http_client/tracing_client.dart +++ b/packages/dart/lib/src/http_client/tracing_client.dart @@ -4,7 +4,7 @@ import '../hub.dart'; import '../hub_adapter.dart'; import '../protocol.dart'; import '../sentry_trace_origins.dart'; -import '../tracing.dart'; +import '../tracing/instrumentation/instrumentation.dart'; import '../utils/http_sanitizer.dart'; import '../utils/tracing_utils.dart'; @@ -19,6 +19,7 @@ class TracingClient extends BaseClient { TracingClient({Client? client, Hub? hub}) : _hub = hub ?? HubAdapter(), _client = client ?? Client() { + _spanFactory = _hub.options.spanFactory; if (_hub.options.isTracingEnabled()) { _hub.options.sdk.addIntegration(integrationName); } @@ -26,6 +27,7 @@ class TracingClient extends BaseClient { final Client _client; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Future send(BaseRequest request) async { @@ -37,40 +39,44 @@ class TracingClient extends BaseClient { description += ' ${urlDetails.urlOrFallback}'; } - final currentSpan = _hub.getSpan(); - var span = currentSpan?.startChild( + final parentSpan = _spanFactory.getSpan(_hub); + final instrumentationSpan = _spanFactory.createSpan( + parentSpan, 'http.client', description: description, ); - if (span is NoOpSentrySpan) { - span = null; - } - // Regardless whether tracing is enabled or not, we always want to attach // Sentry trace headers (tracing without performance). if (containsTargetOrMatchesRegExp( _hub.options.tracePropagationTargets, request.url.toString())) { - addTracingHeadersToHttpHeader(request.headers, _hub, span: span); + addTracingHeadersToHttpHeader( + request.headers, + _hub, + span: instrumentationSpan, + ); } - span?.origin = SentryTraceOrigins.autoHttpHttp; - span?.setData('http.request.method', request.method); - urlDetails?.applyToSpan(span); + instrumentationSpan?.origin = SentryTraceOrigins.autoHttpHttp; + instrumentationSpan?.setData('http.request.method', request.method); + urlDetails?.applyToSpan(instrumentationSpan); StreamedResponse? response; try { response = await _client.send(request); - span?.setData('http.response.status_code', response.statusCode); - span?.setData('http.response_content_length', response.contentLength); - span?.status = SpanStatus.fromHttpStatusCode(response.statusCode); + instrumentationSpan?.setData( + 'http.response.status_code', response.statusCode); + instrumentationSpan?.setData( + 'http.response_content_length', response.contentLength); + instrumentationSpan?.status = + SpanStatus.fromHttpStatusCode(response.statusCode); } catch (exception) { - span?.throwable = exception; - span?.status = SpanStatus.internalError(); + instrumentationSpan?.throwable = exception; + instrumentationSpan?.status = SpanStatus.internalError(); rethrow; } finally { - await span?.finish(); + await instrumentationSpan?.finish(); } return response; } diff --git a/packages/dart/lib/src/sentry_baggage.dart b/packages/dart/lib/src/sentry_baggage.dart index 7baecc5309..37232aa4d9 100644 --- a/packages/dart/lib/src/sentry_baggage.dart +++ b/packages/dart/lib/src/sentry_baggage.dart @@ -3,6 +3,7 @@ import 'package:meta/meta.dart'; import 'protocol.dart'; import 'scope.dart'; import 'sentry_options.dart'; +import 'utils/internal_logger.dart'; class SentryBaggage { static const String _sampleRateKeyName = 'sentry-sample_rate'; @@ -11,13 +12,9 @@ class SentryBaggage { static const int _maxChars = 8192; static const int _maxListMember = 64; - SentryBaggage( - this._keyValues, { - this.log, - }); + SentryBaggage(this._keyValues); final Map _keyValues; - final SdkLogCallback? log; String toHeaderString() { final buffer = StringBuffer(); @@ -26,9 +23,8 @@ class SentryBaggage { for (final entry in _keyValues.entries) { if (listMemberCount >= _maxListMember) { - log?.call( - SentryLevel.info, - 'Baggage key ${entry.key} dropped because of max list member.', + internalLogger.info( + () => 'Baggage key ${entry.key} dropped because of max list member.', ); break; } @@ -40,9 +36,9 @@ class SentryBaggage { final totalLengthIfValueAdded = buffer.length + encodedKeyValue.length; if (totalLengthIfValueAdded >= _maxChars) { - log?.call( - SentryLevel.info, - 'Baggage key ${entry.key} dropped because of max baggage chars.', + internalLogger.info( + () => + 'Baggage key ${entry.key} dropped because of max baggage chars.', ); continue; } @@ -51,10 +47,9 @@ class SentryBaggage { buffer.write(encodedKeyValue); separator = ','; } catch (exception, stackTrace) { - log?.call( - SentryLevel.error, - 'Failed to parse the baggage key ${entry.key}.', - exception: exception, + internalLogger.error( + () => 'Failed to parse the baggage key ${entry.key}.', + error: exception, stackTrace: stackTrace, ); // TODO rethrow in options.automatedTestMode (currently not available here to check) @@ -64,33 +59,25 @@ class SentryBaggage { return buffer.toString(); } - factory SentryBaggage.fromHeaderList( - List headerValues, { - SdkLogCallback? log, - }) { + factory SentryBaggage.fromHeaderList(List headerValues) { final keyValues = {}; for (final headerValue in headerValues) { final keyValuesToAdd = _extractKeyValuesFromBaggageString( headerValue, - log: log, ); keyValues.addAll(keyValuesToAdd); } - return SentryBaggage(keyValues, log: log); + return SentryBaggage(keyValues); } - factory SentryBaggage.fromHeader( - String headerValue, { - SdkLogCallback? log, - }) { + factory SentryBaggage.fromHeader(String headerValue) { final keyValues = _extractKeyValuesFromBaggageString( headerValue, - log: log, ); - return SentryBaggage(keyValues, log: log); + return SentryBaggage(keyValues); } @internal @@ -113,9 +100,7 @@ class SentryBaggage { } static Map _extractKeyValuesFromBaggageString( - String headerValue, { - SdkLogCallback? log, - }) { + String headerValue) { final keyValues = {}; final keyValueStrings = headerValue.split(','); @@ -130,10 +115,9 @@ class SentryBaggage { final value = _urlDecode(keyAndValue.last.trim()); keyValues[key] = value; } catch (exception, stackTrace) { - log?.call( - SentryLevel.error, - 'Failed to parse the baggage entry $keyAndValue.', - exception: exception, + internalLogger.error( + () => 'Failed to parse the baggage entry $keyAndValue.', + error: exception, stackTrace: stackTrace, ); } diff --git a/packages/dart/lib/src/sentry_client.dart b/packages/dart/lib/src/sentry_client.dart index af9850f847..38c686ba9d 100644 --- a/packages/dart/lib/src/sentry_client.dart +++ b/packages/dart/lib/src/sentry_client.dart @@ -190,9 +190,8 @@ class SentryClient { var traceContext = scope?.span?.traceContext(); if (traceContext == null) { if (scope != null) { - scope.propagationContext.baggage ??= - SentryBaggage({}, log: _options.log) - ..setValuesFromScope(scope, _options); + scope.propagationContext.baggage ??= SentryBaggage({}) + ..setValuesFromScope(scope, _options); traceContext = SentryTraceContextHeader.fromBaggage( scope.propagationContext.baggage!); } diff --git a/packages/dart/lib/src/sentry_options.dart b/packages/dart/lib/src/sentry_options.dart index 99e861aabc..6a40127734 100644 --- a/packages/dart/lib/src/sentry_options.dart +++ b/packages/dart/lib/src/sentry_options.dart @@ -650,6 +650,15 @@ class SentryOptions { late SentryStackTraceFactory stackTraceFactory = SentryStackTraceFactory(this); + /// Factory for creating instrumentation spans. + /// + /// This can be replaced to use different span implementations + /// (e.g., SentrySpanV2 in the future). + /// + /// Defaults to [LegacyInstrumentationSpanFactory] which uses the legacy [ISentrySpan] API. + @internal + InstrumentationSpanFactory spanFactory = LegacyInstrumentationSpanFactory(); + @visibleForTesting void debugLog( SentryLevel level, diff --git a/packages/dart/lib/src/sentry_trace_context_header.dart b/packages/dart/lib/src/sentry_trace_context_header.dart index f94f772dc7..7d5d5d79ec 100644 --- a/packages/dart/lib/src/sentry_trace_context_header.dart +++ b/packages/dart/lib/src/sentry_trace_context_header.dart @@ -3,7 +3,6 @@ import 'package:meta/meta.dart'; import 'protocol/access_aware_map.dart'; import 'protocol/sentry_id.dart'; import 'sentry_baggage.dart'; -import 'sentry_options.dart'; class SentryTraceContextHeader { SentryTraceContextHeader( @@ -70,10 +69,8 @@ class SentryTraceContextHeader { }; } - SentryBaggage toBaggage({ - SdkLogCallback? log, - }) { - final baggage = SentryBaggage({}, log: log); + SentryBaggage toBaggage() { + final baggage = SentryBaggage({}); baggage.setTraceId(traceId.toString()); baggage.setPublicKey(publicKey); diff --git a/packages/dart/lib/src/sentry_tracer.dart b/packages/dart/lib/src/sentry_tracer.dart index 10132bbb58..0b8e5468db 100644 --- a/packages/dart/lib/src/sentry_tracer.dart +++ b/packages/dart/lib/src/sentry_tracer.dart @@ -367,7 +367,7 @@ class SentryTracer extends ISentrySpan { final context = traceContext(); if (context != null) { - final baggage = context.toBaggage(log: _hub.options.log); + final baggage = context.toBaggage(); return SentryBaggageHeader.fromBaggage(baggage); } return null; diff --git a/packages/dart/lib/src/tracing/instrumentation/instrumentation.dart b/packages/dart/lib/src/tracing/instrumentation/instrumentation.dart new file mode 100644 index 0000000000..8a2c76b21a --- /dev/null +++ b/packages/dart/lib/src/tracing/instrumentation/instrumentation.dart @@ -0,0 +1,5 @@ +/// @internal Instrumentation API for Sentry packages. +library; + +export 'instrumentation_span.dart'; +export 'span_factory.dart'; diff --git a/packages/dart/lib/src/tracing/instrumentation/instrumentation_span.dart b/packages/dart/lib/src/tracing/instrumentation/instrumentation_span.dart new file mode 100644 index 0000000000..265b3900b2 --- /dev/null +++ b/packages/dart/lib/src/tracing/instrumentation/instrumentation_span.dart @@ -0,0 +1,68 @@ +import 'package:meta/meta.dart'; + +import '../../protocol.dart'; +import '../../sentry_span_interface.dart'; + +/// Opaque span handle enabling swappable tracing backends. +@internal +abstract class InstrumentationSpan { + void setData(String key, dynamic value); + void setTag(String key, String value); + SpanStatus? get status; + set status(SpanStatus? status); + dynamic get throwable; + set throwable(dynamic throwable); + String? get origin; + set origin(String? origin); + Future finish({SpanStatus? status, DateTime? endTimestamp}); + SentryTraceHeader toSentryTrace(); + SentryBaggageHeader? toBaggageHeader(); +} + +/// [InstrumentationSpan] implementation wrapping [ISentrySpan]. +@internal +class LegacyInstrumentationSpan implements InstrumentationSpan { + final ISentrySpan _span; + + LegacyInstrumentationSpan(this._span); + + @internal + ISentrySpan get spanReference => _span; + + @override + void setData(String key, dynamic value) => _span.setData(key, value); + + @override + void setTag(String key, String value) => _span.setTag(key, value); + + @override + SpanStatus? get status => _span.status; + + @override + set status(SpanStatus? status) => _span.status = status; + + @override + dynamic get throwable => _span.throwable; + + @override + set throwable(dynamic throwable) => _span.throwable = throwable; + + @override + String? get origin => _span.origin; + + @override + set origin(String? origin) => _span.origin = origin; + + @override + Future finish({ + SpanStatus? status, + DateTime? endTimestamp, + }) => + _span.finish(status: status, endTimestamp: endTimestamp); + + @override + SentryTraceHeader toSentryTrace() => _span.toSentryTrace(); + + @override + SentryBaggageHeader? toBaggageHeader() => _span.toBaggageHeader(); +} diff --git a/packages/dart/lib/src/tracing/instrumentation/span_factory.dart b/packages/dart/lib/src/tracing/instrumentation/span_factory.dart new file mode 100644 index 0000000000..fc94c4ea58 --- /dev/null +++ b/packages/dart/lib/src/tracing/instrumentation/span_factory.dart @@ -0,0 +1,55 @@ +import 'package:meta/meta.dart'; + +import '../../hub.dart'; +import '../../noop_sentry_span.dart'; +import 'instrumentation_span.dart'; + +/// Factory for creating [InstrumentationSpan] instances. +/// Configure via [SentryOptions.spanFactory]. +@internal +abstract class InstrumentationSpanFactory { + /// Returns `null` if parent is null or span creation fails. + InstrumentationSpan? createSpan( + InstrumentationSpan? parent, + String operation, { + String? description, + DateTime? startTimestamp, + }); + + /// Returns `null` if no active span or tracing disabled. + InstrumentationSpan? getSpan(Hub hub); +} + +/// Default [InstrumentationSpanFactory] using [ISentrySpan]. +@internal +class LegacyInstrumentationSpanFactory implements InstrumentationSpanFactory { + @override + InstrumentationSpan? createSpan( + InstrumentationSpan? parent, + String operation, { + String? description, + DateTime? startTimestamp, + }) { + if (parent == null) return null; + + if (parent is LegacyInstrumentationSpan) { + final child = parent.spanReference.startChild( + operation, + description: description, + startTimestamp: startTimestamp, + ); + + if (child is NoOpSentrySpan) return null; + return LegacyInstrumentationSpan(child); + } + + return null; + } + + @override + InstrumentationSpan? getSpan(Hub hub) { + final span = hub.getSpan(); + if (span == null || span is NoOpSentrySpan) return null; + return LegacyInstrumentationSpan(span); + } +} diff --git a/packages/dart/lib/src/utils/tracing_utils.dart b/packages/dart/lib/src/utils/tracing_utils.dart index 30595fc4f6..e89ab3a92d 100644 --- a/packages/dart/lib/src/utils/tracing_utils.dart +++ b/packages/dart/lib/src/utils/tracing_utils.dart @@ -7,8 +7,11 @@ SentryTraceHeader generateSentryTraceHeader( return SentryTraceHeader(traceId, spanId, sampled: sampled); } -void addTracingHeadersToHttpHeader(Map headers, Hub hub, - {ISentrySpan? span}) { +void addTracingHeadersToHttpHeader( + Map headers, + Hub hub, { + InstrumentationSpan? span, +}) { if (span != null) { if (hub.options.propagateTraceparent) { addW3CHeaderFromSpan(span, headers); @@ -17,14 +20,13 @@ void addTracingHeadersToHttpHeader(Map headers, Hub hub, addBaggageHeaderFromSpan( span, headers, - log: hub.options.log, ); } else { if (hub.options.propagateTraceparent) { addW3CHeaderFromScope(hub.scope, headers); } addSentryTraceHeaderFromScope(hub.scope, headers); - addBaggageHeaderFromScope(hub.scope, headers, log: hub.options.log); + addBaggageHeaderFromScope(hub.scope, headers); } } @@ -35,7 +37,7 @@ void addSentryTraceHeaderFromScope(Scope scope, Map headers) { } void addSentryTraceHeaderFromSpan( - ISentrySpan span, Map headers) { + InstrumentationSpan span, Map headers) { final traceHeader = span.toSentryTrace(); headers[traceHeader.name] = traceHeader.value; } @@ -45,7 +47,8 @@ void addSentryTraceHeader( headers[traceHeader.name] = traceHeader.value; } -void addW3CHeaderFromSpan(ISentrySpan span, Map headers) { +void addW3CHeaderFromSpan( + InstrumentationSpan span, Map headers) { final traceHeader = span.toSentryTrace(); _addW3CHeaderFromSentryTrace(traceHeader, headers); } @@ -67,42 +70,30 @@ String formatAsW3CHeader(SentryTraceHeader traceHeader) { return '00-${traceHeader.traceId}-${traceHeader.spanId}-$sampledBit'; } -void addBaggageHeaderFromScope( - Scope scope, - Map headers, { - SdkLogCallback? log, -}) { +void addBaggageHeaderFromScope(Scope scope, Map headers) { final baggageHeader = scope.propagationContext.toBaggageHeader(); if (baggageHeader != null) { - addBaggageHeader(baggageHeader, headers, log: log); + addBaggageHeader(baggageHeader, headers); } } void addBaggageHeaderFromSpan( - ISentrySpan span, - Map headers, { - SdkLogCallback? log, -}) { + InstrumentationSpan span, Map headers) { final baggage = span.toBaggageHeader(); if (baggage != null) { - addBaggageHeader(baggage, headers, log: log); + addBaggageHeader(baggage, headers); } } void addBaggageHeader( - SentryBaggageHeader baggage, - Map headers, { - SdkLogCallback? log, -}) { + SentryBaggageHeader baggage, Map headers) { final currentValue = headers[baggage.name] as String? ?? ''; final currentBaggage = SentryBaggage.fromHeader( currentValue, - log: log, ); final sentryBaggage = SentryBaggage.fromHeader( baggage.value, - log: log, ); // overwrite sentry's keys https://develop.sentry.dev/sdk/performance/dynamic-sampling-context/#baggage @@ -114,7 +105,7 @@ void addBaggageHeader( ...sentryBaggage.keyValues, }; - final newBaggage = SentryBaggage(mergedBaggage, log: log); + final newBaggage = SentryBaggage(mergedBaggage); headers[baggage.name] = newBaggage.toHeaderString(); } diff --git a/packages/dart/lib/src/utils/url_details.dart b/packages/dart/lib/src/utils/url_details.dart index 4cc47510a6..1835a916e6 100644 --- a/packages/dart/lib/src/utils/url_details.dart +++ b/packages/dart/lib/src/utils/url_details.dart @@ -15,7 +15,7 @@ class UrlDetails { late final urlOrFallback = Uri.tryParse(url ?? _unknown)?.toString() ?? _unknown; - void applyToSpan(ISentrySpan? span) { + void applyToSpan(InstrumentationSpan? span) { if (span == null) { return; } diff --git a/packages/dart/test/mocks/mock_span.dart b/packages/dart/test/mocks/mock_span.dart new file mode 100644 index 0000000000..32f44dd95d --- /dev/null +++ b/packages/dart/test/mocks/mock_span.dart @@ -0,0 +1,8 @@ +import 'package:mockito/mockito.dart'; +import 'package:sentry/sentry.dart'; + +class MockSpan extends Mock implements SentrySpan { + final SentrySpanContext _context = SentrySpanContext(operation: 'test'); + @override + SentrySpanContext get context => _context; +} diff --git a/packages/dart/test/sentry_client_lifecycle_test.dart b/packages/dart/test/sentry_client_lifecycle_test.dart index 9e94217e6c..4d04d5a8c2 100644 --- a/packages/dart/test/sentry_client_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_lifecycle_test.dart @@ -4,11 +4,11 @@ import 'package:sentry/src/sentry_tracer.dart'; import 'package:test/test.dart'; import 'mocks/mock_client_report_recorder.dart'; +import 'mocks/mock_span.dart'; import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'sentry_client_test.dart'; import 'test_utils.dart'; -import 'utils/url_details_test.dart'; void main() { group('SDK lifecycle callbacks', () { diff --git a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart index 9de1f753c7..487b1dfff9 100644 --- a/packages/dart/test/sentry_client_sdk_lifecycle_test.dart +++ b/packages/dart/test/sentry_client_sdk_lifecycle_test.dart @@ -4,11 +4,11 @@ import 'package:sentry/src/sentry_tracer.dart'; import 'package:test/test.dart'; import 'mocks/mock_client_report_recorder.dart'; +import 'mocks/mock_span.dart'; import 'mocks/mock_telemetry_processor.dart'; import 'mocks/mock_transport.dart'; import 'sentry_client_test.dart'; import 'test_utils.dart'; -import 'utils/url_details_test.dart'; void main() { group('SDK lifecycle callbacks', () { diff --git a/packages/dart/test/utils/tracing_utils_test.dart b/packages/dart/test/utils/tracing_utils_test.dart index 36587ea904..b630e6e239 100644 --- a/packages/dart/test/utils/tracing_utils_test.dart +++ b/packages/dart/test/utils/tracing_utils_test.dart @@ -58,7 +58,7 @@ void main() { final sut = fixture.getSut(); final sentryHeader = sut.toSentryTrace(); - addSentryTraceHeaderFromSpan(sut, headers); + addSentryTraceHeaderFromSpan(LegacyInstrumentationSpan(sut), headers); expect(headers[sentryHeader.name], sentryHeader.value); }); @@ -92,7 +92,7 @@ void main() { final headers = {}; final sut = fixture.getSut(); - addW3CHeaderFromSpan(sut, headers); + addW3CHeaderFromSpan(LegacyInstrumentationSpan(sut), headers); expect(headers[headerName], '00-${fixture._context.traceId}-${fixture._context.spanId}-01'); @@ -134,7 +134,7 @@ void main() { final sut = fixture.getSut(); final baggage = sut.toBaggageHeader(); - addBaggageHeaderFromSpan(sut, headers); + addBaggageHeaderFromSpan(LegacyInstrumentationSpan(sut), headers); expect(headers[baggage!.name], baggage.value); }); @@ -149,7 +149,7 @@ void main() { final newValue = '$oldValue,${baggage!.value}'; - addBaggageHeaderFromSpan(sut, headers); + addBaggageHeaderFromSpan(LegacyInstrumentationSpan(sut), headers); expect(headers[baggage.name], newValue); }); @@ -164,7 +164,7 @@ void main() { final sut = fixture.getSut(); final baggage = sut.toBaggageHeader(); - addBaggageHeaderFromSpan(sut, headers); + addBaggageHeaderFromSpan(LegacyInstrumentationSpan(sut), headers); expect(headers[baggage!.name], 'other-vendor-value=foo,sentry-trace_id=${sut.context.traceId},sentry-public_key=public,sentry-release=release,sentry-environment=environment,sentry-transaction=name,sentry-sample_rate=1,sentry-sampled=true'); @@ -262,7 +262,8 @@ void main() { final span = fixture.getSut(); hub.options.propagateTraceparent = true; - addTracingHeadersToHttpHeader(headers, hub, span: span); + addTracingHeadersToHttpHeader(headers, hub, + span: LegacyInstrumentationSpan(span)); expect(headers['traceparent'], '00-${fixture._context.traceId}-${fixture._context.spanId}-01'); @@ -316,7 +317,8 @@ void main() { final hub = fixture._hub; final span = fixture.getSut(); - addTracingHeadersToHttpHeader(headers, hub, span: span); + addTracingHeadersToHttpHeader(headers, hub, + span: LegacyInstrumentationSpan(span)); final traceHeader = SentryTraceHeader.fromTraceHeader(headers['sentry-trace']); diff --git a/packages/dart/test/utils/url_details_test.dart b/packages/dart/test/utils/url_details_test.dart index 673d4452da..cd1a8a731b 100644 --- a/packages/dart/test/utils/url_details_test.dart +++ b/packages/dart/test/utils/url_details_test.dart @@ -12,7 +12,7 @@ void main() { test('applies all to span', () { final urlDetails = UrlDetails(url: "https://sentry.io/api", query: "q=1", fragment: "top"); - final span = MockSpan(); + final span = MockInstrumentationSpan(); urlDetails.applyToSpan(span); verify(span.setData("url", "https://sentry.io/api")); @@ -22,7 +22,7 @@ void main() { test('applies only url to span', () { final urlDetails = UrlDetails(url: "https://sentry.io/api"); - final span = MockSpan(); + final span = MockInstrumentationSpan(); urlDetails.applyToSpan(span); verify(span.setData("url", "https://sentry.io/api")); @@ -31,7 +31,7 @@ void main() { test('applies only query to span', () { final urlDetails = UrlDetails(query: "q=1"); - final span = MockSpan(); + final span = MockInstrumentationSpan(); urlDetails.applyToSpan(span); verify(span.setData("http.query", "q=1")); @@ -40,7 +40,7 @@ void main() { test('applies only fragment to span', () { final urlDetails = UrlDetails(fragment: "top"); - final span = MockSpan(); + final span = MockInstrumentationSpan(); urlDetails.applyToSpan(span); verify(span.setData("http.fragment", "top")); @@ -86,8 +86,4 @@ void main() { }); } -class MockSpan extends Mock implements SentrySpan { - final SentrySpanContext _context = SentrySpanContext(operation: 'test'); - @override - SentrySpanContext get context => _context; -} +class MockInstrumentationSpan extends Mock implements InstrumentationSpan {} diff --git a/packages/dio/lib/src/sentry_transformer.dart b/packages/dio/lib/src/sentry_transformer.dart index f5fb7c8ac4..e39f088fe8 100644 --- a/packages/dio/lib/src/sentry_transformer.dart +++ b/packages/dio/lib/src/sentry_transformer.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'package:dio/dio.dart'; import 'package:sentry/sentry.dart'; @@ -8,27 +10,30 @@ class SentryTransformer implements Transformer { // ignore: public_member_api_docs SentryTransformer({required Transformer transformer, Hub? hub}) : _hub = hub ?? HubAdapter(), - _transformer = transformer; + _transformer = transformer { + _spanFactory = _hub.options.spanFactory; + } final Transformer _transformer; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Future transformRequest(RequestOptions options) async { - // ignore: invalid_use_of_internal_member final urlDetails = HttpSanitizer.sanitizeUrl(options.uri.toString()); var description = options.method; if (urlDetails != null) { description += ' ${urlDetails.urlOrFallback}'; } - final span = _hub.getSpan()?.startChild( - _serializeOp, - description: description, - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + _serializeOp, + description: description, + ); span?.setData('http.request.method', options.method); - // ignore: invalid_use_of_internal_member span?.origin = SentryTraceOrigins.autoHttpDioTransformer; urlDetails?.applyToSpan(span); @@ -53,20 +58,20 @@ class SentryTransformer implements Transformer { RequestOptions options, ResponseBody response, ) async { - // ignore: invalid_use_of_internal_member final urlDetails = HttpSanitizer.sanitizeUrl(options.uri.toString()); var description = options.method; if (urlDetails != null) { description += ' ${urlDetails.urlOrFallback}'; } - final span = _hub.getSpan()?.startChild( - _serializeOp, - description: description, - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + _serializeOp, + description: description, + ); span?.setData('http.request.method', options.method); - // ignore: invalid_use_of_internal_member span?.origin = SentryTraceOrigins.autoHttpDioTransformer; urlDetails?.applyToSpan(span); diff --git a/packages/dio/lib/src/tracing_client_adapter.dart b/packages/dio/lib/src/tracing_client_adapter.dart index 438f51f185..a056075f51 100644 --- a/packages/dio/lib/src/tracing_client_adapter.dart +++ b/packages/dio/lib/src/tracing_client_adapter.dart @@ -18,6 +18,7 @@ class TracingClientAdapter implements HttpClientAdapter { TracingClientAdapter({required HttpClientAdapter client, Hub? hub}) : _hub = hub ?? HubAdapter(), _client = client { + _spanFactory = _hub.options.spanFactory; if (_hub.options.isTracingEnabled()) { _hub.options.sdk.addIntegration(integrationName); } @@ -25,6 +26,7 @@ class TracingClientAdapter implements HttpClientAdapter { final HttpClientAdapter _client; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Future fetch( @@ -40,46 +42,55 @@ class TracingClientAdapter implements HttpClientAdapter { } // see https://develop.sentry.dev/sdk/performance/#header-sentry-trace - final currentSpan = _hub.getSpan(); - var span = currentSpan?.startChild( + final parentSpan = _spanFactory.getSpan(_hub); + final instrumentationSpan = _spanFactory.createSpan( + parentSpan, 'http.client', description: description, ); - if (span is NoOpSentrySpan) { - span = null; - } - // Regardless whether tracing is enabled or not, we always want to attach // Sentry trace headers (tracing without performance). if (containsTargetOrMatchesRegExp( _hub.options.tracePropagationTargets, options.uri.toString(), )) { - addTracingHeadersToHttpHeader(options.headers, _hub, span: span); + addTracingHeadersToHttpHeader( + options.headers, + _hub, + span: instrumentationSpan, + ); } - span?.origin = SentryTraceOrigins.autoHttpDioHttpClientAdapter; - span?.setData('http.request.method', options.method); - urlDetails?.applyToSpan(span); + instrumentationSpan?.origin = + SentryTraceOrigins.autoHttpDioHttpClientAdapter; + instrumentationSpan?.setData('http.request.method', options.method); + urlDetails?.applyToSpan(instrumentationSpan); ResponseBody? response; try { response = await _client.fetch(options, requestStream, cancelFuture); - span?.status = SpanStatus.fromHttpStatusCode(response.statusCode); - span?.setData('http.response.status_code', response.statusCode); + instrumentationSpan?.status = + SpanStatus.fromHttpStatusCode(response.statusCode); + instrumentationSpan?.setData( + 'http.response.status_code', + response.statusCode, + ); final contentLengthHeader = HttpHeaderUtils.getContentLength(response.headers); if (contentLengthHeader != null) { - span?.setData('http.response_content_length', contentLengthHeader); + instrumentationSpan?.setData( + 'http.response_content_length', + contentLengthHeader, + ); } } catch (exception) { - span?.throwable = exception; - span?.status = const SpanStatus.internalError(); + instrumentationSpan?.throwable = exception; + instrumentationSpan?.status = const SpanStatus.internalError(); rethrow; } finally { - await span?.finish(); + await instrumentationSpan?.finish(); } return response; } diff --git a/packages/drift/lib/src/constants.dart b/packages/drift/lib/src/constants.dart index c096dbc0af..c1be0a71d6 100644 --- a/packages/drift/lib/src/constants.dart +++ b/packages/drift/lib/src/constants.dart @@ -1,2 +1 @@ const String integrationName = 'sentryDriftTracing'; -const String loggerName = 'sentry_drift'; diff --git a/packages/drift/lib/src/internal_logger.dart b/packages/drift/lib/src/internal_logger.dart new file mode 100644 index 0000000000..29bd38f4fe --- /dev/null +++ b/packages/drift/lib/src/internal_logger.dart @@ -0,0 +1,5 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +@internal +const internalLogger = SentryInternalLogger('sentry_drift'); diff --git a/packages/drift/lib/src/sentry_span_helper.dart b/packages/drift/lib/src/sentry_span_helper.dart index 466c120eeb..bd9e286aab 100644 --- a/packages/drift/lib/src/sentry_span_helper.dart +++ b/packages/drift/lib/src/sentry_span_helper.dart @@ -1,27 +1,38 @@ // ignore_for_file: invalid_use_of_internal_member import 'dart:collection'; +import 'dart:async'; import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -import 'constants.dart'; +import 'internal_logger.dart'; @internal class SentrySpanHelper { final Hub _hub; final String _origin; + late final InstrumentationSpanFactory _factory; /// Represents a stack of Drift transaction spans. /// These are used to allow nested spans if the user nests Drift transactions. /// If the transaction stack is empty, the spans are attached to the /// active span in the Hub's scope. - final ListQueue _transactionStack = ListQueue(); + final ListQueue _transactionStack = ListQueue(); @visibleForTesting - ListQueue get transactionStack => _transactionStack; + ListQueue get transactionStack => _transactionStack; - SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter(); + SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter() { + _factory = _hub.options.spanFactory; + } + + /// Gets the parent span for operations. + /// Returns the last transaction on the stack, or falls back to the current + /// span from the hub's scope if the stack is empty. + InstrumentationSpan? _getParent() { + return _transactionStack.lastOrNull ?? _factory.getSpan(_hub); + } Future asyncWrapInSpan( String description, @@ -29,21 +40,24 @@ class SentrySpanHelper { String? dbName, String? operation, }) async { - final parentSpan = _transactionStack.lastOrNull ?? _hub.getSpan(); + final parentSpan = _getParent(); if (parentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not start span for the Drift operation: $description', - logger: loggerName, + internalLogger.warning( + 'No active span found. Skipping tracing for Drift operation: $description', ); return execute(); } - final span = parentSpan.startChild( + final span = _factory.createSpan( + parentSpan, operation ?? SentrySpanOperations.dbSqlQuery, description: description, ); + if (span == null) { + return execute(); + } + span.origin = _origin; span.setData( @@ -74,21 +88,24 @@ class SentrySpanHelper { T Function() execute, { String? dbName, }) { - final parentSpan = _transactionStack.lastOrNull ?? _hub.getSpan(); + final parentSpan = _getParent(); if (parentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not start span for Drift operation: Begin Transaction', - logger: loggerName, + internalLogger.warning( + 'No active span found. Skipping tracing for Drift beginTransaction.', ); return execute(); } - final newParent = parentSpan.startChild( + final newParent = _factory.createSpan( + parentSpan, SentrySpanOperations.dbSqlTransaction, description: SentrySpanDescriptions.dbTransaction, ); + if (newParent == null) { + return execute(); + } + newParent.origin = _origin; newParent.setData( @@ -104,29 +121,28 @@ class SentrySpanHelper { final result = execute(); newParent.status = SpanStatus.unknown(); - // Only add to the stack if no error occurred _transactionStack.add(newParent); return result; } catch (exception) { newParent.throwable = exception; newParent.status = SpanStatus.internalError(); + unawaited(newParent.finish()); rethrow; } } Future finishTransaction(Future Function() execute) async { - final parentSpan = _transactionStack.lastOrNull; - if (parentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not finish span for Drift operation: Finish Transaction', - logger: loggerName, + if (_transactionStack.isEmpty) { + internalLogger.warning( + 'Transaction stack is empty. Skipping span finish for Drift commitTransaction.', ); return execute(); } + final parentSpan = _transactionStack.last; + try { final result = await execute(); parentSpan.status = SpanStatus.ok(); @@ -144,16 +160,15 @@ class SentrySpanHelper { } Future abortTransaction(Future Function() execute) async { - final parentSpan = _transactionStack.lastOrNull; - if (parentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not finish span for Drift operation: Abort Transaction', - logger: loggerName, + if (_transactionStack.isEmpty) { + internalLogger.warning( + 'Transaction stack is empty. Skipping span finish for Drift rollbackTransaction.', ); return execute(); } + final parentSpan = _transactionStack.last; + try { final result = await execute(); parentSpan.status = SpanStatus.aborted(); diff --git a/packages/drift/test/sentry_drift_test.dart b/packages/drift/test/sentry_drift_test.dart index 27ce6b8320..d55ce999ef 100644 --- a/packages/drift/test/sentry_drift_test.dart +++ b/packages/drift/test/sentry_drift_test.dart @@ -10,6 +10,7 @@ import 'package:sentry/sentry.dart'; import 'package:sentry/src/sentry_tracer.dart'; import 'package:sentry_drift/src/constants.dart' as drift_constants; import 'package:sentry_drift/src/sentry_query_interceptor.dart'; +import 'package:sentry_drift/src/sentry_span_helper.dart'; import 'package:sentry_drift/src/version.dart'; import 'package:sqlite3/open.dart'; @@ -692,6 +693,30 @@ void main() { tx.children.last, ); }); + + test('beginTransaction error finishes span to prevent leak', () async { + final exception = Exception('beginTransaction failed'); + final queryExecutor = MockQueryExecutor(); + when(queryExecutor.ensureOpen(any)).thenAnswer((_) => Future.value(true)); + when(queryExecutor.beginTransaction()).thenThrow(exception); + when(queryExecutor.dialect).thenReturn(SqlDialect.sqlite); + + final sut = fixture.getSut(); + final db = AppDatabase(queryExecutor.interceptWith(sut)); + + final tx = _startTransaction(); + try { + await db.transaction(() async { + await _insertRow(db); + }); + } catch (e) { + // expected + } + + final transactionSpan = tx.children.last; + expect(transactionSpan.finished, isTrue); + expect(sut.spanHelper.transactionStack, isEmpty); + }); }); group('integrations', () { @@ -718,6 +743,62 @@ void main() { ); }); }); + + group('span creation failure', () { + test('beginTransaction executes successfully when createSpan returns null', + () async { + final mockHub = MockHub(); + final mockOptions = defaultTestOptions()..tracesSampleRate = 1.0; + + // Set up a factory that returns null from createSpan + final nullSpanFactory = _NullSpanFactory(); + mockOptions.spanFactory = nullSpanFactory; + + when(mockHub.options).thenReturn(mockOptions); + + final spanHelper = SentrySpanHelper( + SentryTraceOrigins.autoDbDriftQueryInterceptor, + hub: mockHub, + ); + + // Create a mock parent span for getSpan to return + final tx = _startTransaction(); + nullSpanFactory.mockParentSpan = + LegacyInstrumentationSpan(tx.startChild('test')); + + var executed = false; + spanHelper.beginTransaction(() { + executed = true; + return 'result'; + }); + + expect(executed, isTrue); + // Stack should remain empty since we don't push when createSpan returns null + expect(spanHelper.transactionStack, isEmpty); + }); + }); +} + +/// A factory that returns a valid span from getSpan but null from createSpan. +/// This simulates the case where span creation fails (e.g., span limit reached). +class _NullSpanFactory implements InstrumentationSpanFactory { + InstrumentationSpan? mockParentSpan; + + @override + InstrumentationSpan? createSpan( + InstrumentationSpan? parent, + String operation, { + String? description, + DateTime? startTimestamp, + }) { + // Always return null to simulate span creation failure + return null; + } + + @override + InstrumentationSpan? getSpan(Hub hub) { + return mockParentSpan; + } } class Fixture { diff --git a/packages/file/lib/src/sentry_file.dart b/packages/file/lib/src/sentry_file.dart index ec2d2c99f7..b989f43ff7 100644 --- a/packages/file/lib/src/sentry_file.dart +++ b/packages/file/lib/src/sentry_file.dart @@ -239,12 +239,14 @@ class SentryFile implements File { this._file, { @internal Hub? hub, }) : _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; _hub.options.sdk.addIntegration('SentryFileTracing'); _hub.options.sdk.addPackage(packageName, sdkVersion); } final File _file; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Future copy(String newPath) { @@ -421,8 +423,12 @@ class SentryFile implements File { Future _wrap(Callback callback, String operation) async { final desc = _getDesc(); - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild(operation, description: desc); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + operation, + description: desc, + ); span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', true); @@ -484,8 +490,12 @@ class SentryFile implements File { T _wrapSync(Callback callback, String operation) { final desc = _getDesc(); - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild(operation, description: desc); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + operation, + description: desc, + ); span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', false); @@ -533,7 +543,7 @@ class SentryFile implements File { span?.status = SpanStatus.internalError(); rethrow; } finally { - span?.finish(); + unawaited(span?.finish()); _hub.addBreadcrumb( Breadcrumb( diff --git a/packages/hive/lib/src/sentry_box.dart b/packages/hive/lib/src/sentry_box.dart index b3123cd792..ee107f1836 100644 --- a/packages/hive/lib/src/sentry_box.dart +++ b/packages/hive/lib/src/sentry_box.dart @@ -11,14 +11,15 @@ class SentryBox extends SentryBoxBase implements Box { final Box _box; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxBase, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryBox(this._box, @internal this._hub) : super(_box, _hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxBase, + hub: _hub, + ); } @override diff --git a/packages/hive/lib/src/sentry_box_base.dart b/packages/hive/lib/src/sentry_box_base.dart index df08118335..46798f2eda 100644 --- a/packages/hive/lib/src/sentry_box_base.dart +++ b/packages/hive/lib/src/sentry_box_base.dart @@ -9,14 +9,15 @@ class SentryBoxBase implements BoxBase { final BoxBase _boxBase; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxBase, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryBoxBase(this._boxBase, this._hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxBase, + hub: _hub, + ); } @override diff --git a/packages/hive/lib/src/sentry_box_collection.dart b/packages/hive/lib/src/sentry_box_collection.dart index 48f28f60f1..8503d7b9c3 100644 --- a/packages/hive/lib/src/sentry_box_collection.dart +++ b/packages/hive/lib/src/sentry_box_collection.dart @@ -6,7 +6,6 @@ import 'package:hive/src/box_collection/box_collection_stub.dart' as impl; // ignore: implementation_imports import 'package:hive/src/box_collection/box_collection_stub.dart' as stub; -import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; import 'sentry_span_helper.dart'; @@ -15,13 +14,16 @@ import 'sentry_span_helper.dart'; class SentryBoxCollection implements stub.BoxCollection { final impl.BoxCollection _boxCollection; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxCollection, - ); + late final SentrySpanHelper _spanHelper; /// Init with [impl.BoxCollection] - SentryBoxCollection(this._boxCollection); + SentryBoxCollection(this._boxCollection, {Hub? hub}) { + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxCollection, + hub: hub ?? HubAdapter(), + ); + } @override Set get boxNames => _boxCollection.boxNames; @@ -31,12 +33,6 @@ class SentryBoxCollection implements stub.BoxCollection { _boxCollection.close(); } - /// @nodoc - @internal - void setHub(Hub hub) { - _spanHelper.setHub(hub); - } - @override Future deleteFromDisk() { return _spanHelper.asyncWrapInSpan( @@ -59,11 +55,12 @@ class SentryBoxCollection implements stub.BoxCollection { HiveCipher? key, Hub? hub, }) async { + final resolvedHub = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbHiveBoxCollection, + hub: resolvedHub, ); - spanHelper.setHub(hub ?? HubAdapter()); return await spanHelper.asyncWrapInSpan( 'open', @@ -74,9 +71,7 @@ class SentryBoxCollection implements stub.BoxCollection { path: path, key: key, ); - final sbc = SentryBoxCollection(boxCollection); - sbc.setHub(hub ?? HubAdapter()); - return sbc; + return SentryBoxCollection(boxCollection, hub: resolvedHub); }, dbName: name, ); diff --git a/packages/hive/lib/src/sentry_hive_impl.dart b/packages/hive/lib/src/sentry_hive_impl.dart index 83e0e2234a..ceca7640ac 100644 --- a/packages/hive/lib/src/sentry_hive_impl.dart +++ b/packages/hive/lib/src/sentry_hive_impl.dart @@ -33,13 +33,16 @@ class SentryHiveImpl implements SentryHiveInterface { final HiveInterface _hive; Hub _hub = HubAdapter(); - /// @nodoc - SentryHiveImpl(this._hive); + late SentrySpanHelper _spanHelper; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHive, - ); + /// @nodoc + SentryHiveImpl(this._hive) { + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHive, + hub: _hub, + ); + } // SentryHiveInterface @@ -50,7 +53,11 @@ class SentryHiveImpl implements SentryHiveInterface { options.sdk.addIntegration('SentryHiveTracing'); options.sdk.addPackage(packageName, sdkVersion); _hub = hub; - _spanHelper.setHub(hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHive, + hub: hub, + ); } // HiveInterface diff --git a/packages/hive/lib/src/sentry_lazy_box.dart b/packages/hive/lib/src/sentry_lazy_box.dart index 86eabb9fdd..b6b33eb43f 100644 --- a/packages/hive/lib/src/sentry_lazy_box.dart +++ b/packages/hive/lib/src/sentry_lazy_box.dart @@ -11,14 +11,15 @@ class SentryLazyBox extends SentryBoxBase implements LazyBox { final LazyBox _lazyBox; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveLazyBox, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryLazyBox(this._lazyBox, @internal this._hub) : super(_lazyBox, _hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveLazyBox, + hub: _hub, + ); } @override diff --git a/packages/hive/lib/src/sentry_span_helper.dart b/packages/hive/lib/src/sentry_span_helper.dart index 3df56b248b..99b5f8994e 100644 --- a/packages/hive/lib/src/sentry_span_helper.dart +++ b/packages/hive/lib/src/sentry_span_helper.dart @@ -1,22 +1,22 @@ +// ignore_for_file: invalid_use_of_internal_member + +import 'dart:async'; + import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; + import 'sentry_hive_impl.dart'; /// @nodoc @internal class SentrySpanHelper { - /// @nodoc - Hub _hub = HubAdapter(); - - /// @nodoc + final Hub _hub; final String _origin; + late final InstrumentationSpanFactory _factory; /// @nodoc - SentrySpanHelper(this._origin); - - /// @nodoc - void setHub(Hub hub) { - _hub = hub; + SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter() { + _factory = _hub.options.spanFactory; } /// @nodoc @@ -26,50 +26,41 @@ class SentrySpanHelper { Future Function() execute, { String? dbName, }) async { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + final span = _factory.createSpan( + parentSpan, SentryHiveImpl.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member span?.origin = _origin; - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); if (dbName != null) { span?.setData(SentryHiveImpl.dbNameKey, dbName); } - breadcrumb.data?[SentryHiveImpl.dbSystemKey] = SentryHiveImpl.dbSystem; - if (dbName != null) { - breadcrumb.data?[SentryHiveImpl.dbNameKey] = dbName; - } + final breadcrumb = Breadcrumb( + message: description, + data: { + SentryHiveImpl.dbSystemKey: SentryHiveImpl.dbSystem, + if (dbName != null) SentryHiveImpl.dbNameKey: dbName, + }, + type: 'query', + ); try { final result = await execute(); - span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { span?.throwable = exception; span?.status = SpanStatus.internalError(); - breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { await span?.finish(); - - // ignore: invalid_use_of_internal_member await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -81,51 +72,42 @@ class SentrySpanHelper { T Function() execute, { String? dbName, }) { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + final span = _factory.createSpan( + parentSpan, SentryHiveImpl.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member span?.origin = _origin; span?.setData('sync', true); - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); if (dbName != null) { span?.setData(SentryHiveImpl.dbNameKey, dbName); } - breadcrumb.data?[SentryHiveImpl.dbSystemKey] = SentryHiveImpl.dbSystem; - if (dbName != null) { - breadcrumb.data?[SentryHiveImpl.dbNameKey] = dbName; - } + final breadcrumb = Breadcrumb( + message: description, + data: { + SentryHiveImpl.dbSystemKey: SentryHiveImpl.dbSystem, + if (dbName != null) SentryHiveImpl.dbNameKey: dbName, + }, + type: 'query', + ); try { final result = execute(); - span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { span?.throwable = exception; span?.status = SpanStatus.internalError(); - breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - span?.finish(); - - // ignore: invalid_use_of_internal_member + unawaited(span?.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } diff --git a/packages/hive/test/sentry_box_collection_test.dart b/packages/hive/test/sentry_box_collection_test.dart index d62ebf6ffe..ef1af559b6 100644 --- a/packages/hive/test/sentry_box_collection_test.dart +++ b/packages/hive/test/sentry_box_collection_test.dart @@ -384,9 +384,7 @@ class Fixture { Future getSut({bool injectMock = false}) async { if (injectMock) { - final sbc = SentryBoxCollection(mockBoxCollection); - sbc.setHub(hub); - return sbc; + return SentryBoxCollection(mockBoxCollection, hub: hub); } else { return await SentryBoxCollection.open(dbName, {'people'}, hub: hub); } diff --git a/packages/isar/lib/src/internal_logger.dart b/packages/isar/lib/src/internal_logger.dart new file mode 100644 index 0000000000..83776ba137 --- /dev/null +++ b/packages/isar/lib/src/internal_logger.dart @@ -0,0 +1,5 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +@internal +const internalLogger = SentryInternalLogger('sentry_isar'); diff --git a/packages/isar/lib/src/sentry_isar.dart b/packages/isar/lib/src/sentry_isar.dart index 3d36bb58a5..7ea36613ca 100644 --- a/packages/isar/lib/src/sentry_isar.dart +++ b/packages/isar/lib/src/sentry_isar.dart @@ -30,14 +30,15 @@ class SentryIsar implements Isar { final Isar _isar; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbIsar, - ); + late final SentrySpanHelper _spanHelper; /// ctor of SentryIsar SentryIsar(this._isar, this._hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbIsar, + hub: _hub, + ); // ignore: invalid_use_of_internal_member final options = _hub.options; @@ -56,12 +57,12 @@ class SentryIsar implements Isar { bool inspector = true, Hub? hub, }) async { + final hubToUse = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbIsar, + hub: hubToUse, ); - final hubToUse = hub ?? HubAdapter(); - spanHelper.setHub(hubToUse); final isar = await spanHelper.asyncWrapInSpan( 'open', @@ -93,12 +94,12 @@ class SentryIsar implements Isar { bool inspector = true, Hub? hub, }) { + final hubToUse = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbIsar, + hub: hubToUse, ); - final hubToUse = hub ?? HubAdapter(); - spanHelper.setHub(hubToUse); final isar = spanHelper.syncWrapInSpan( 'openSync', diff --git a/packages/isar/lib/src/sentry_isar_collection.dart b/packages/isar/lib/src/sentry_isar_collection.dart index d79dfb8bb7..6d9ec28608 100644 --- a/packages/isar/lib/src/sentry_isar_collection.dart +++ b/packages/isar/lib/src/sentry_isar_collection.dart @@ -11,15 +11,15 @@ class SentryIsarCollection implements IsarCollection { final IsarCollection _isarCollection; final Hub _hub; final String _dbName; - - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbIsarCollection, - ); + late final SentrySpanHelper _spanHelper; /// ctor of SentryIsarCollection SentryIsarCollection(this._isarCollection, this._hub, this._dbName) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbIsarCollection, + hub: _hub, + ); } @override diff --git a/packages/isar/lib/src/sentry_span_helper.dart b/packages/isar/lib/src/sentry_span_helper.dart index 50624b300a..f6d4998ad4 100644 --- a/packages/isar/lib/src/sentry_span_helper.dart +++ b/packages/isar/lib/src/sentry_span_helper.dart @@ -1,24 +1,22 @@ -// ignore_for_file: invalid_internal_annotation +// ignore_for_file: invalid_use_of_internal_member + +import 'dart:async'; import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; + import 'sentry_isar.dart'; /// @nodoc @internal class SentrySpanHelper { - /// @nodoc - Hub _hub = HubAdapter(); - - /// @nodoc + final Hub _hub; final String _origin; + late final InstrumentationSpanFactory _factory; /// @nodoc - SentrySpanHelper(this._origin); - - /// @nodoc - void setHub(Hub hub) { - _hub = hub; + SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter() { + _factory = _hub.options.spanFactory; } /// @nodoc @@ -29,52 +27,45 @@ class SentrySpanHelper { String? dbName, String? collectionName, }) async { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + final span = _factory.createSpan( + parentSpan, SentryIsar.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member span?.origin = _origin; - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); - if (dbName != null) { span?.setData(SentryIsar.dbNameKey, dbName); - breadcrumb.data?[SentryIsar.dbNameKey] = dbName; } - if (collectionName != null) { span?.setData(SentryIsar.dbCollectionKey, collectionName); - breadcrumb.data?[SentryIsar.dbCollectionKey] = collectionName; } + final breadcrumb = Breadcrumb( + message: description, + data: { + SentryIsar.dbSystemKey: SentryIsar.dbSystem, + if (dbName != null) SentryIsar.dbNameKey: dbName, + if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, + }, + type: 'query', + ); + try { final result = await execute(); - span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { span?.throwable = exception; span?.status = SpanStatus.internalError(); - breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { await span?.finish(); - - // ignore: invalid_use_of_internal_member await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -87,53 +78,46 @@ class SentrySpanHelper { String? dbName, String? collectionName, }) { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + final span = _factory.createSpan( + parentSpan, SentryIsar.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member span?.origin = _origin; span?.setData('sync', true); - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); - if (dbName != null) { span?.setData(SentryIsar.dbNameKey, dbName); - breadcrumb.data?[SentryIsar.dbNameKey] = dbName; } - if (collectionName != null) { span?.setData(SentryIsar.dbCollectionKey, collectionName); - breadcrumb.data?[SentryIsar.dbCollectionKey] = collectionName; } + final breadcrumb = Breadcrumb( + message: description, + data: { + SentryIsar.dbSystemKey: SentryIsar.dbSystem, + if (dbName != null) SentryIsar.dbNameKey: dbName, + if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, + }, + type: 'query', + ); + try { final result = execute(); - span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { span?.throwable = exception; span?.status = SpanStatus.internalError(); - breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - span?.finish(); - - // ignore: invalid_use_of_internal_member + unawaited(span?.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } diff --git a/packages/link/lib/src/sentry_request_serializer.dart b/packages/link/lib/src/sentry_request_serializer.dart index 1d766bd900..4f656e262d 100644 --- a/packages/link/lib/src/sentry_request_serializer.dart +++ b/packages/link/lib/src/sentry_request_serializer.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -7,17 +9,23 @@ import 'package:sentry/sentry.dart'; class SentryRequestSerializer implements RequestSerializer { SentryRequestSerializer({RequestSerializer? inner, Hub? hub}) : inner = inner ?? const RequestSerializer(), - _hub = hub ?? HubAdapter(); + _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final RequestSerializer inner; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Map serializeRequest(Request request) { - final span = _hub.getSpan()?.startChild( - 'serialize.http.client', - description: 'GraphGL request serialization', - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + 'serialize.http.client', + description: 'GraphGL request serialization', + ); + Map result; try { result = inner.serializeRequest(request); diff --git a/packages/link/lib/src/sentry_response_parser.dart b/packages/link/lib/src/sentry_response_parser.dart index ab02e7f46a..b391617bff 100644 --- a/packages/link/lib/src/sentry_response_parser.dart +++ b/packages/link/lib/src/sentry_response_parser.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -7,18 +9,24 @@ import 'package:sentry/sentry.dart'; class SentryResponseParser implements ResponseParser { SentryResponseParser({ResponseParser? inner, Hub? hub}) : inner = inner ?? const ResponseParser(), - _hub = hub ?? HubAdapter(); + _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final ResponseParser inner; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Response parseResponse(Map body) { - final span = _hub.getSpan()?.startChild( - 'serialize.http.client', - description: 'Response deserialization ' - 'from JSON map to Response object', - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + 'serialize.http.client', + description: 'Response deserialization ' + 'from JSON map to Response object', + ); + Response result; try { result = inner.parseResponse(body); diff --git a/packages/link/lib/src/sentry_tracing_link.dart b/packages/link/lib/src/sentry_tracing_link.dart index 93c420eed9..46adb49570 100644 --- a/packages/link/lib/src/sentry_tracing_link.dart +++ b/packages/link/lib/src/sentry_tracing_link.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -18,9 +20,12 @@ class SentryTracingLink extends Link { required this.shouldStartTransaction, required this.graphQlErrorsMarkTransactionAsFailed, Hub? hub, - }) : _hub = hub ?? HubAdapter(); + }) : _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; /// If [shouldStartTransaction] is set to true, a [SentryTransaction] /// is automatically created for each GraphQL query/mutation. @@ -44,7 +49,7 @@ class SentryTracingLink extends Link { final sentryOperation = operationType?.sentryOperation ?? 'unknown'; final sentryType = operationType?.sentryType; - final transaction = _startSpan( + final span = _startSpan( 'GraphQL: "${request.operation.operationName ?? 'unnamed'}" $sentryType', sentryOperation, shouldStartTransaction, @@ -53,9 +58,9 @@ class SentryTracingLink extends Link { handleData: (data, sink) { final hasGraphQlError = data.errors?.isNotEmpty ?? false; if (graphQlErrorsMarkTransactionAsFailed && hasGraphQlError) { - transaction?.finish(status: const SpanStatus.unknownError()); + unawaited(span?.finish(status: const SpanStatus.unknownError())); } else { - transaction?.finish(status: const SpanStatus.ok()); + unawaited(span?.finish(status: const SpanStatus.ok())); } sink.add(data); @@ -67,24 +72,28 @@ class SentryTracingLink extends Link { // The correct `SpanStatus` can be set on // `HttpLinkResponseContext.statusCode` or // `DioLinkResponseContext.statusCode` - transaction?.throwable = error; - unawaited(transaction?.finish(status: const SpanStatus.unknownError())); + span?.throwable = error; + unawaited(span?.finish(status: const SpanStatus.unknownError())); sink.addError(error, stackTrace); }, )); } - ISentrySpan? _startSpan( - String op, + InstrumentationSpan? _startSpan( String description, + String op, bool shouldStartTransaction, ) { - final span = _hub.getSpan(); - if (span == null && shouldStartTransaction) { - return _hub.startTransaction(description, op, bindToScope: true); - } else if (span != null) { - return span.startChild(op, description: description); + final parentSpan = _spanFactory.getSpan(_hub); + if (parentSpan == null && shouldStartTransaction) { + // Start a new transaction - InstrumentationSpan doesn't support this + // so we use the legacy API and wrap it + final transaction = + _hub.startTransaction(description, op, bindToScope: true); + return LegacyInstrumentationSpan(transaction); + } else if (parentSpan != null) { + return _spanFactory.createSpan(parentSpan, op, description: description); } return null; } diff --git a/packages/sqflite/lib/src/sentry_batch.dart b/packages/sqflite/lib/src/sentry_batch.dart index c5f7ea15d3..51b9cb08a7 100644 --- a/packages/sqflite/lib/src/sentry_batch.dart +++ b/packages/sqflite/lib/src/sentry_batch.dart @@ -27,6 +27,9 @@ class SentryBatch implements Batch { // we don't clear the buffer because SqfliteBatch don't either final _buffer = StringBuffer(); + // ignore: invalid_use_of_internal_member + late final InstrumentationSpanFactory _spanFactory; + /// ```dart /// import 'package:sqflite/sqflite.dart'; /// import 'package:sentry_sqflite/sentry_sqflite.dart'; @@ -40,14 +43,18 @@ class SentryBatch implements Batch { @internal Hub? hub, @internal String? dbName, }) : _hub = hub ?? HubAdapter(), - _dbName = dbName; + _dbName = dbName { + // ignore: invalid_use_of_internal_member + _spanFactory = _hub.options.spanFactory; + } @override Future> apply({bool? noResult, bool? continueOnError}) { return Future>(() async { - final currentSpan = _hub.getSpan(); + final parent = _spanFactory.getSpan(_hub); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbOp, description: _buffer.toString().trim(), ); @@ -98,9 +105,10 @@ class SentryBatch implements Batch { bool? continueOnError, }) { return Future>(() async { - final currentSpan = _hub.getSpan(); + final parent = _spanFactory.getSpan(_hub); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbOp, description: _buffer.toString().trim(), ); diff --git a/packages/sqflite/lib/src/sentry_database.dart b/packages/sqflite/lib/src/sentry_database.dart index 7b94ef1d5c..ce1de7432f 100644 --- a/packages/sqflite/lib/src/sentry_database.dart +++ b/packages/sqflite/lib/src/sentry_database.dart @@ -51,6 +51,9 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { // ignore: public_member_api_docs String dbName; + // ignore: invalid_use_of_internal_member + late final InstrumentationSpanFactory _spanFactory; + /// ```dart /// import 'package:sqflite/sqflite.dart'; /// import 'package:sentry_sqflite/sentry_sqflite.dart'; @@ -70,6 +73,8 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { ) { // ignore: invalid_use_of_internal_member final options = _hub.options; + // ignore: invalid_use_of_internal_member + _spanFactory = options.spanFactory; options.sdk.addIntegration('SentrySqfliteTracing'); options.sdk.addPackage(packageName, sdkVersion); } @@ -79,9 +84,10 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { @override Future close() { return Future(() async { - final currentSpan = _hub.getSpan(); + final parent = _spanFactory.getSpan(_hub); final description = 'Close DB: ${_database.path}'; - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, dbOp, description: description, ); @@ -143,9 +149,10 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { bool? exclusive, }) { return Future(() async { - final currentSpan = _hub.getSpan(); + final parent = _spanFactory.getSpan(_hub); final description = 'Transaction DB: ${_database.path}'; - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, _dbSqlTransactionOp, description: description, ); @@ -202,9 +209,10 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { // ignore: override_on_non_overriding_member, public_member_api_docs Future readTransaction(Future Function(Transaction txn) action) { return Future(() async { - final currentSpan = _hub.getSpan(); + final parent = _spanFactory.getSpan(_hub); final description = 'Transaction DB: ${_database.path}'; - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, _dbSqlReadTransactionOp, description: description, ); diff --git a/packages/sqflite/lib/src/sentry_database_executor.dart b/packages/sqflite/lib/src/sentry_database_executor.dart index 61853413b7..0992a7b976 100644 --- a/packages/sqflite/lib/src/sentry_database_executor.dart +++ b/packages/sqflite/lib/src/sentry_database_executor.dart @@ -13,20 +13,34 @@ import 'utils/sentry_database_span_attributes.dart'; // ignore: public_member_api_docs class SentryDatabaseExecutor implements DatabaseExecutor { final DatabaseExecutor _executor; - final ISentrySpan? _parentSpan; + // ignore: invalid_use_of_internal_member + final InstrumentationSpan? _parentSpan; final String? _dbName; // ignore: public_member_api_docs SentryDatabaseExecutor( this._executor, { - ISentrySpan? parentSpan, + // ignore: invalid_use_of_internal_member + InstrumentationSpan? parentSpan, @internal Hub? hub, @internal String? dbName, }) : _parentSpan = parentSpan, _hub = hub ?? HubAdapter(), - _dbName = dbName; + _dbName = dbName { + // ignore: invalid_use_of_internal_member + _spanFactory = _hub.options.spanFactory; + } + final Hub _hub; + // ignore: invalid_use_of_internal_member + late final InstrumentationSpanFactory _spanFactory; + + // ignore: invalid_use_of_internal_member + InstrumentationSpan? _getParent() { + return _parentSpan ?? _spanFactory.getSpan(_hub); + } + @override Batch batch() => SentryBatch(_executor.batch(), hub: _hub, dbName: _dbName); @@ -36,10 +50,11 @@ class SentryDatabaseExecutor implements DatabaseExecutor { @override Future delete(String table, {String? where, List? whereArgs}) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); + final parent = _getParent(); final builder = SqlBuilder.delete(table, where: where, whereArgs: whereArgs); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); @@ -81,12 +96,12 @@ class SentryDatabaseExecutor implements DatabaseExecutor { @override Future execute(String sql, [List? arguments]) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: sql, ); - span?.setData(SentryDatabase.dbSystemKey, SentryDatabase.dbSystem); // ignore: invalid_use_of_internal_member span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; setDatabaseAttributeData(span, _dbName); @@ -127,14 +142,15 @@ class SentryDatabaseExecutor implements DatabaseExecutor { ConflictAlgorithm? conflictAlgorithm, }) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); + final parent = _getParent(); final builder = SqlBuilder.insert( table, values, nullColumnHack: nullColumnHack, conflictAlgorithm: conflictAlgorithm, ); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); @@ -191,7 +207,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor { int? offset, }) { return Future>>(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); + final parent = _getParent(); final builder = SqlBuilder.query( table, distinct: distinct, @@ -204,7 +220,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { offset: offset, whereArgs: whereArgs, ); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlQueryOp, description: builder.sql, ); @@ -268,7 +285,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor { int? bufferSize, }) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); + final parent = _getParent(); final builder = SqlBuilder.query( table, distinct: distinct, @@ -281,7 +298,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { offset: offset, whereArgs: whereArgs, ); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlQueryOp, description: builder.sql, ); @@ -334,8 +352,9 @@ class SentryDatabaseExecutor implements DatabaseExecutor { @override Future rawDelete(String sql, [List? arguments]) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: sql, ); @@ -376,8 +395,9 @@ class SentryDatabaseExecutor implements DatabaseExecutor { @override Future rawInsert(String sql, [List? arguments]) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: sql, ); @@ -421,8 +441,9 @@ class SentryDatabaseExecutor implements DatabaseExecutor { List? arguments, ]) { return Future>>(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlQueryOp, description: sql, ); @@ -467,8 +488,9 @@ class SentryDatabaseExecutor implements DatabaseExecutor { int? bufferSize, }) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlQueryOp, description: sql, ); @@ -513,8 +535,9 @@ class SentryDatabaseExecutor implements DatabaseExecutor { @override Future rawUpdate(String sql, [List? arguments]) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); - final span = currentSpan?.startChild( + final parent = _getParent(); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: sql, ); @@ -561,7 +584,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor { ConflictAlgorithm? conflictAlgorithm, }) { return Future(() async { - final currentSpan = _parentSpan ?? _hub.getSpan(); + final parent = _getParent(); final builder = SqlBuilder.update( table, values, @@ -569,7 +592,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { whereArgs: whereArgs, conflictAlgorithm: conflictAlgorithm, ); - final span = currentSpan?.startChild( + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); diff --git a/packages/sqflite/lib/src/sentry_sqflite.dart b/packages/sqflite/lib/src/sentry_sqflite.dart index bcc183ddb2..c03e7d3da4 100644 --- a/packages/sqflite/lib/src/sentry_sqflite.dart +++ b/packages/sqflite/lib/src/sentry_sqflite.dart @@ -39,9 +39,12 @@ Future openDatabaseWithSentry( final newHub = hub ?? HubAdapter(); - final currentSpan = newHub.getSpan(); + // ignore: invalid_use_of_internal_member + final spanFactory = newHub.options.spanFactory; final description = 'Open DB: $path'; - final span = currentSpan?.startChild( + final parent = spanFactory.getSpan(newHub); + final span = spanFactory.createSpan( + parent, SentryDatabase.dbOp, description: description, ); diff --git a/packages/sqflite/lib/src/sentry_sqflite_database_factory.dart b/packages/sqflite/lib/src/sentry_sqflite_database_factory.dart index f1bb787546..c949e29481 100644 --- a/packages/sqflite/lib/src/sentry_sqflite_database_factory.dart +++ b/packages/sqflite/lib/src/sentry_sqflite_database_factory.dart @@ -36,11 +36,17 @@ class SentrySqfliteDatabaseFactory with SqfliteDatabaseFactoryMixin { sqflite.DatabaseFactory? databaseFactory, @internal Hub? hub, }) : _databaseFactory = databaseFactory ?? sqflite.databaseFactory, - _hub = hub ?? HubAdapter(); + _hub = hub ?? HubAdapter() { + // ignore: invalid_use_of_internal_member + _spanFactory = _hub.options.spanFactory; + } final Hub _hub; final sqflite.DatabaseFactory _databaseFactory; + // ignore: invalid_use_of_internal_member + late final InstrumentationSpanFactory _spanFactory; + @override Future invokeMethod(String method, [Object? arguments]) => impl.invokeMethod(method, arguments); @@ -58,9 +64,10 @@ class SentrySqfliteDatabaseFactory with SqfliteDatabaseFactoryMixin { } return Future(() async { - final currentSpan = _hub.getSpan(); final description = 'Open DB: $path'; - final span = currentSpan?.startChild( + final parent = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parent, SentryDatabase.dbOp, description: description, ); diff --git a/packages/sqflite/lib/src/utils/sentry_database_span_attributes.dart b/packages/sqflite/lib/src/utils/sentry_database_span_attributes.dart index 347c750ee8..999fb6c85c 100644 --- a/packages/sqflite/lib/src/utils/sentry_database_span_attributes.dart +++ b/packages/sqflite/lib/src/utils/sentry_database_span_attributes.dart @@ -2,9 +2,14 @@ import 'package:sentry/sentry.dart'; import '../../sentry_sqflite.dart'; -/// Sets the database attributes on the [span]. +/// Sets the database attributes on the [span] using InstrumentationSpan. /// It contains the database system and the database name. -void setDatabaseAttributeData(ISentrySpan? span, String? dbName) { +// ignore: invalid_use_of_internal_member +void setDatabaseAttributeData( + // ignore: invalid_use_of_internal_member + InstrumentationSpan? span, + String? dbName, +) { span?.setData(SentryDatabase.dbSystemKey, SentryDatabase.dbSystem); if (dbName != null) { span?.setData(SentryDatabase.dbNameKey, dbName); diff --git a/packages/supabase/lib/src/internal_logger.dart b/packages/supabase/lib/src/internal_logger.dart new file mode 100644 index 0000000000..dc60f19aa4 --- /dev/null +++ b/packages/supabase/lib/src/internal_logger.dart @@ -0,0 +1,5 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +@internal +const internalLogger = SentryInternalLogger('sentry_supabase'); diff --git a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart index 6aa5ebc365..32f980f783 100644 --- a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart +++ b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart @@ -3,14 +3,17 @@ import 'package:http/http.dart'; import 'package:sentry/sentry.dart'; -import 'constants.dart'; +import 'internal_logger.dart'; import 'sentry_supabase_request.dart'; class SentrySupabaseTracingClient extends BaseClient { final Client _innerClient; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; - SentrySupabaseTracingClient(this._innerClient, this._hub); + SentrySupabaseTracingClient(this._innerClient, this._hub) { + _spanFactory = _hub.options.spanFactory; + } @override Future send(BaseRequest request) async { @@ -56,21 +59,25 @@ class SentrySupabaseTracingClient extends BaseClient { // Helper - ISentrySpan? _createSpan(SentrySupabaseRequest supabaseRequest) { - final currentSpan = _hub.getSpan(); - if (currentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not start span for the Supabase operation: from(${supabaseRequest.table})', - logger: loggerName, + InstrumentationSpan? _createSpan(SentrySupabaseRequest supabaseRequest) { + final parentSpan = _spanFactory.getSpan(_hub); + if (parentSpan == null) { + internalLogger.warning( + 'No active span found. Skipping tracing for Supabase operation: from(${supabaseRequest.table})', ); return null; } - final span = currentSpan.startChild( + + final span = _spanFactory.createSpan( + parentSpan, 'db.${supabaseRequest.operation.value}', description: 'from(${supabaseRequest.table})', ); + if (span == null) { + return null; + } + final dbSchema = supabaseRequest.request.headers['Accept-Profile'] ?? supabaseRequest.request.headers['Content-Profile']; if (dbSchema != null) { diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 076a4ab71f..b27e927dd1 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -10,6 +10,7 @@ environment: dependencies: http: ^1.3.0 + meta: ^1.3.0 sentry: 9.11.0-beta.1 dev_dependencies: From 5238eef2e499406aa97b3ec78da38eec8185b62a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:46:31 +0100 Subject: [PATCH 35/62] build(deps): bump actions/checkout from 5 to 6 (#3460) Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/kotlin-version-compatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kotlin-version-compatibility.yml b/.github/workflows/kotlin-version-compatibility.yml index 8d7669c5f9..992fd8807c 100644 --- a/.github/workflows/kotlin-version-compatibility.yml +++ b/.github/workflows/kotlin-version-compatibility.yml @@ -37,7 +37,7 @@ jobs: KOTLIN_ANDROID_PLUGIN_VERSION: ${{ matrix.kotlin_android_plugin_version }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup Java uses: actions/setup-java@v5 From 47e51574c597ecf230804f5813d9f10473363a8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:47:09 +0100 Subject: [PATCH 36/62] build(deps): bump ruby/setup-ruby from 1.278.0 to 1.286.0 (#3482) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.278.0 to 1.286.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/4c24fa5ec04b2e79eb40571b1cee2a0d2b705771...90be1154f987f4dc0fe0dd0feedac9e473aa4ba8) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.286.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/min_version_test.yml | 2 +- .github/workflows/testflight.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/min_version_test.yml b/.github/workflows/min_version_test.yml index 399ba4b732..613538f0a7 100644 --- a/.github/workflows/min_version_test.yml +++ b/.github/workflows/min_version_test.yml @@ -51,7 +51,7 @@ jobs: with: flutter-version: '3.24.0' - - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 + - uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # pin@v1.286.0 with: ruby-version: '3.1.2' # https://github.com/flutter/flutter/issues/109385#issuecomment-1212614125 diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 8d058aea95..91b6d53530 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - run: xcodes select 26.2 - - uses: ruby/setup-ruby@4c24fa5ec04b2e79eb40571b1cee2a0d2b705771 # pin@v1.278.0 + - uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # pin@v1.286.0 with: ruby-version: '2.7.5' bundler-cache: true From b6df2e3fda9a8aef53089135784bfb4be2819f19 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 29 Jan 2026 15:55:52 +0100 Subject: [PATCH 37/62] fix(dart): Catch client exceptions in HttpTransport.send (#3490) * fix(dart): Catch client exceptions in HttpTransport.send Prevents unhandled exceptions like `ClientException: Connection closed before full header was received` from crashing the host application. The error is logged via internalLogger and only rethrown in automatedTestMode. Co-Authored-By: Claude Opus 4.5 * Update * Update CHANGELOG * Update * Update * Implement lost event recording in HttpTransport for network errors Enhance the HttpTransport class to record lost events when a network error occurs during envelope transmission. This includes logging discarded events for both Sentry transactions and spans. Add corresponding tests to verify the functionality when client exceptions are thrown. * Refactor lost event handling in HttpTransport and TransportUtils Consolidate lost event recording logic into TransportUtils for better reusability. Update HttpTransport to utilize the new method for recording lost events on network errors. Enhance logging for response statuses, including rate limit handling. Remove redundant lost event recording method from HttpTransport. * Update * Update * Rename to recordLostEvents --------- Co-authored-by: Claude Opus 4.5 --- CHANGELOG.md | 4 + .../lib/src/transport/http_transport.dart | 34 ++++-- .../transport/spotlight_http_transport.dart | 3 +- .../dart/lib/src/utils/transport_utils.dart | 53 +++++---- .../test/transport/http_transport_test.dart | 106 ++++++++++++++---- 5 files changed, 139 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b545eb0d12..e5b3aaecf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- Catch client exceptions in HttpTransport.send ([#3490](https://github.com/getsentry/sentry-dart/pull/3490)) + ### Internals - Remove deprecated `beforeMetricCallback` from options ([#3484](https://github.com/getsentry/sentry-dart/pull/3450)) diff --git a/packages/dart/lib/src/transport/http_transport.dart b/packages/dart/lib/src/transport/http_transport.dart index 73c8e41c69..1653eae6e8 100644 --- a/packages/dart/lib/src/transport/http_transport.dart +++ b/packages/dart/lib/src/transport/http_transport.dart @@ -5,10 +5,12 @@ import 'package:http/http.dart'; import '../http_client/client_provider.dart' if (dart.library.io) '../http_client/io_client_provider.dart'; +import '../client_reports/discard_reason.dart'; import '../noop_client.dart'; import '../protocol.dart'; import '../sentry_envelope.dart'; import '../sentry_options.dart'; +import '../utils/internal_logger.dart'; import '../utils/transport_utils.dart'; import 'http_transport_request_handler.dart'; import 'rate_limiter.dart'; @@ -39,20 +41,35 @@ class HttpTransport implements Transport { final streamedRequest = await _requestHandler.createRequest(envelope); - final response = await _options.httpClient - .send(streamedRequest) - .then(Response.fromStream); + final Response response; + try { + response = await _options.httpClient + .send(streamedRequest) + .then(Response.fromStream); + } catch (error, stackTrace) { + internalLogger.error('Failed to send envelope', + error: error, stackTrace: stackTrace); + TransportUtils.recordLostEvents( + _options, envelope, DiscardReason.networkError); + if (_options.automatedTestMode) { + rethrow; + } + return SentryId.empty(); + } _updateRetryAfterLimits(response); - TransportUtils.logResponse(_options, envelope, response, target: 'Sentry'); + TransportUtils.logResponse(envelope, response, target: 'Sentry'); if (response.statusCode == 200) { return _parseEventId(response); } + if (response.statusCode >= 400 && response.statusCode != 429) { + TransportUtils.recordLostEvents( + _options, envelope, DiscardReason.networkError); + } if (response.statusCode == 429) { - _options.log( - SentryLevel.warning, 'Rate limit reached, failed to send envelope'); + internalLogger.warning('Rate limit reached, failed to send envelope'); } return SentryId.empty(); } @@ -61,8 +78,9 @@ class HttpTransport implements Transport { try { final eventId = json.decode(response.body)['id']; return eventId != null ? SentryId.fromId(eventId) : null; - } catch (e) { - _options.log(SentryLevel.error, 'Error parsing response: $e'); + } catch (error, stackTrace) { + internalLogger.error('Error parsing response', + error: error, stackTrace: stackTrace); if (_options.automatedTestMode) { rethrow; } diff --git a/packages/dart/lib/src/transport/spotlight_http_transport.dart b/packages/dart/lib/src/transport/spotlight_http_transport.dart index e2c98fda2a..0942f14b91 100644 --- a/packages/dart/lib/src/transport/spotlight_http_transport.dart +++ b/packages/dart/lib/src/transport/spotlight_http_transport.dart @@ -49,8 +49,7 @@ class SpotlightHttpTransport extends Transport { .send(spotlightRequest) .then(Response.fromStream); - TransportUtils.logResponse(_options, envelope, response, - target: 'Spotlight'); + TransportUtils.logResponse(envelope, response, target: 'Spotlight'); } } diff --git a/packages/dart/lib/src/utils/transport_utils.dart b/packages/dart/lib/src/utils/transport_utils.dart index 3dae120d58..36a4275cf8 100644 --- a/packages/dart/lib/src/utils/transport_utils.dart +++ b/packages/dart/lib/src/utils/transport_utils.dart @@ -5,41 +5,38 @@ import '../protocol.dart'; import '../sentry_envelope.dart'; import '../sentry_options.dart'; import '../transport/data_category.dart'; +import 'internal_logger.dart'; class TransportUtils { - static void logResponse( - SentryOptions options, SentryEnvelope envelope, Response response, + static void logResponse(SentryEnvelope envelope, Response response, {required String target}) { if (response.statusCode != 200) { - if (options.debug) { - options.log( - SentryLevel.error, - 'Error, statusCode = ${response.statusCode}, body = ${response.body}', - ); - } + internalLogger.error(() => + 'Failed to send envelope, statusCode = ${response.statusCode}, body = ${response.body}'); + } else { + internalLogger.debug( + () => + 'Envelope ${envelope.header.eventId ?? "--"} was sent successfully to $target.', + ); + } + } - if (response.statusCode >= 400 && response.statusCode != 429) { - for (final item in envelope.items) { - options.recorder.recordLostEvent( - DiscardReason.networkError, - DataCategory.fromItemType(item.header.type), - ); + static void recordLostEvents( + SentryOptions options, SentryEnvelope envelope, DiscardReason reason) { + for (final item in envelope.items) { + options.recorder.recordLostEvent( + reason, + DataCategory.fromItemType(item.header.type), + ); - final originalObject = item.originalObject; - if (originalObject is SentryTransaction) { - options.recorder.recordLostEvent( - DiscardReason.networkError, - DataCategory.span, - count: originalObject.spans.length + 1, - ); - } - } + final originalObject = item.originalObject; + if (originalObject is SentryTransaction) { + options.recorder.recordLostEvent( + reason, + DataCategory.span, + count: originalObject.spans.length + 1, + ); } - } else { - options.log( - SentryLevel.debug, - 'Envelope ${envelope.header.eventId ?? "--"} was sent successfully to $target.', - ); } } } diff --git a/packages/dart/test/transport/http_transport_test.dart b/packages/dart/test/transport/http_transport_test.dart index 0c0307a4b5..3576c238f0 100644 --- a/packages/dart/test/transport/http_transport_test.dart +++ b/packages/dart/test/transport/http_transport_test.dart @@ -50,6 +50,89 @@ void main() { expect(body, envelopeData); }); + + test('returns empty SentryId when client throws exception', () async { + final httpMock = MockClient((http.Request request) async { + throw http.ClientException( + 'Connection closed before full header was received'); + }); + + fixture.options.automatedTestMode = false; + final sut = fixture.getSut(httpMock, MockRateLimiter()); + + final sentryEvent = SentryEvent(); + final envelope = SentryEnvelope.fromEvent( + sentryEvent, + fixture.options.sdk, + dsn: fixture.options.dsn, + ); + + final result = await sut.send(envelope); + + expect(result, SentryId.empty()); + }); + + test('records lost event when client throws exception', () async { + final httpMock = MockClient((http.Request request) async { + throw http.ClientException( + 'Connection closed before full header was received'); + }); + + fixture.options.automatedTestMode = false; + final sut = fixture.getSut(httpMock, MockRateLimiter()); + + final sentryEvent = SentryEvent(); + final envelope = SentryEnvelope.fromEvent( + sentryEvent, + fixture.options.sdk, + dsn: fixture.options.dsn, + ); + + await sut.send(envelope); + + expect(fixture.clientReportRecorder.discardedEvents.length, 1); + expect(fixture.clientReportRecorder.discardedEvents.first.reason, + DiscardReason.networkError); + expect(fixture.clientReportRecorder.discardedEvents.first.category, + DataCategory.error); + }); + + test('records lost transaction and spans when client throws exception', + () async { + final httpMock = MockClient((http.Request request) async { + throw http.ClientException( + 'Connection closed before full header was received'); + }); + + fixture.options.automatedTestMode = false; + final sut = fixture.getSut(httpMock, MockRateLimiter()); + + final transaction = fixture.getTransaction(); + transaction.tracer.startChild('child1'); + transaction.tracer.startChild('child2'); + final envelope = SentryEnvelope.fromTransaction( + transaction, + fixture.options.sdk, + dsn: fixture.options.dsn, + ); + + await sut.send(envelope); + + final transactionDiscardedEvent = fixture + .clientReportRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.transaction && + element.reason == DiscardReason.networkError); + + final spanDiscardedEvent = fixture.clientReportRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.networkError); + + expect(transactionDiscardedEvent, isNotNull); + expect(spanDiscardedEvent, isNotNull); + expect(spanDiscardedEvent!.quantity, 3); + }); }); group('updateRetryAfterLimits', () { @@ -83,10 +166,6 @@ void main() { expect(mockRateLimiter.errorCode, 429); expect(mockRateLimiter.retryAfterHeader, '1'); expect(mockRateLimiter.sentryRateLimitHeader, isNull); - - expect(fixture.loggedLevel, SentryLevel.warning); - expect( - fixture.loggedMessage, 'Rate limit reached, failed to send envelope'); }); test('sentryRateLimitHeader', () async { @@ -236,10 +315,6 @@ void main() { await sut.send(envelope); expect(fixture.clientReportRecorder.discardedEvents.isEmpty, isTrue); - - expect(fixture.loggedLevel, SentryLevel.warning); - expect( - fixture.loggedMessage, 'Rate limit reached, failed to send envelope'); }); test('does record lost event for error >= 500', () async { @@ -271,7 +346,6 @@ class Fixture { HttpTransport getSut(http.Client client, RateLimiter rateLimiter) { options.debug = true; - options.log = mockLogger; options.httpClient = client; options.recorder = clientReportRecorder; options.clock = () { @@ -289,18 +363,4 @@ class Fixture { final tracer = SentryTracer(context, MockHub()); return SentryTransaction(tracer); } - - SentryLevel? loggedLevel; - String? loggedMessage; - - void mockLogger( - SentryLevel level, - String message, { - String? logger, - Object? exception, - StackTrace? stackTrace, - }) { - loggedLevel = level; - loggedMessage = message; - } } From ccf07957bff3e56d60b0ecf2690f45978779b585 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 29 Jan 2026 15:47:52 +0000 Subject: [PATCH 38/62] release: 9.11.0-beta.2 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5b3aaecf1..c520f8dfc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.11.0-beta.2 ### Fixes diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index 0fc0e0e3c6..d01764e7da 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.11.0-beta.2 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.1 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.10.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.9.2 | 8.28.0 | 8.56.2 | 10.6.0 | 0.10.0 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index 4c7193efbd..c445414860 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 4501f87fc6..41fb75be30 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index d4125dcb5a..f3a4e8b61a 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index d1bb7792d7..2dc054c07a 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index 0c42c42ca2..5b798748d9 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 5b91abe4b6..8a3dd9ff68 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index ca7499e2e2..201e40a0e0 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index da9541e593..abf885c29e 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index 6858109abf..c73ed4078b 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index 76a21abe17..e7d35185d1 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index c6d17f4ee3..6f98624083 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 22d7e1c19e..fe89ebbcdb 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index 9f9dc73438..fb11c2ac72 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index 71a180ad82..1637cd4a2b 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index ec079e8858..de132a536a 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index 0089b1bd30..add302260e 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index f12f83d190..287b929c3a 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index 9893784ca3..12e8fe7047 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index 860320d7b9..00980f0189 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index 578b349e1b..1aee4167bc 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.1'; +const String sdkVersion = '9.11.0-beta.2'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index 77fe131751..ed3aed21c8 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index b27e927dd1..5bb9259dab 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.11.0-beta.1 +version: 9.11.0-beta.2 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: http: ^1.3.0 meta: ^1.3.0 - sentry: 9.11.0-beta.1 + sentry: 9.11.0-beta.2 dev_dependencies: supabase: ^2.6.0 From 628d80897c2cd6898388f2ac84274c1a352493b3 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Tue, 3 Feb 2026 14:59:30 +0100 Subject: [PATCH 39/62] chore(release): prepare `9.11.0` changelog (#3498) * Update CHANGELOG * Revise CHANGELOG for enhancements and dependencies Updated CHANGELOG to reflect enhancements and dependency bumps. --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c520f8dfc0..5fdb38f792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## Unreleased + +### Features + +- Trace connected metrics ([#3450](https://github.com/getsentry/sentry-dart/pull/3450)) + - This feature is enabled by default. + - To send metrics use the following APIs: + - `Sentry.metrics.gauge(...)` + - `Sentry.metrics.count(...)` + - `Sentry.metrics.distribution(...)` + - For more details read the [Flutter metrics documentation](https://docs.sentry.io/platforms/dart/guides/flutter/metrics/). +- Add `captureNativeFailedRequests` option for iOS/macOS ([#3472](https://github.com/getsentry/sentry-dart/pull/3472)) + - This option allows controlling native HTTP error capturing independently from `captureFailedRequests`. + - When `null` (the default), it falls back to `captureFailedRequests` for backwards compatibility. + - Set to `false` to disable native failed request capturing while keeping Dart-side capturing enabled. + +### Fixes + +- Catch client exceptions in HttpTransport.send ([#3490](https://github.com/getsentry/sentry-dart/pull/3490)) + +### Dependencies + +- Bump Android SDK from v8.28.0 to v8.30.0 ([#3451](https://github.com/getsentry/sentry-dart/pull/3451)) + - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8300) + - [diff](https://github.com/getsentry/sentry-java/compare/8.28.0...8.30.0) + +
+Internal Changes + +- Refactor Logging API to be consistent with Metrics ([#3463](https://github.com/getsentry/sentry-dart/pull/3463)) +- Remove deprecated `beforeMetricCallback` from options ([#3484](https://github.com/getsentry/sentry-dart/pull/3450)) +- Add span factory to allow swappable span backends in integrations ([#3488](https://github.com/getsentry/sentry-dart/pull/3450)) + +
+ ## 9.11.0-beta.2 ### Fixes From c6bf794fc4f3c3a5db722735cc61ad6feaa25bc3 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 3 Feb 2026 14:07:20 +0000 Subject: [PATCH 40/62] release: 9.11.0 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fdb38f792..27bb967225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.11.0 ### Features diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index d01764e7da..9a970445b7 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.11.0 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.2 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.1 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.10.0 | 8.28.0 | 8.56.2 | 10.6.0 | 0.12.3 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index c445414860..cf7fbb03e9 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 41fb75be30..1ca6e9f365 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.11.0-beta.2 +version: 9.11.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index f3a4e8b61a..4114a528cd 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index 2dc054c07a..3a70f6c181 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.11.0-beta.2 + sentry: 9.11.0 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index 5b798748d9..f6609e9fa4 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 8a3dd9ff68..1438dae8d9 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0-beta.2 + sentry: 9.11.0 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 201e40a0e0..82174c75bd 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index abf885c29e..52c1dd4b6e 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.11.0-beta.2 + sentry: 9.11.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index c73ed4078b..2e9d88d122 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.11.0-beta.2 + sentry: 9.11.0 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index e7d35185d1..a514371bfa 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.11.0-beta.2 +version: 9.11.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 6f98624083..39b905dcb3 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index fe89ebbcdb..665fe9d1e4 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.11.0-beta.2 +version: 9.11.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.11.0-beta.2 + sentry: 9.11.0 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index fb11c2ac72..cd3ad92c9f 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index 1637cd4a2b..48e399d6e8 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0-beta.2 + sentry: 9.11.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index de132a536a..302cb54830 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index add302260e..5b51961113 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.11.0-beta.2 + sentry: 9.11.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index 287b929c3a..458126af10 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.11.0-beta.2 + sentry: 9.11.0 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index 12e8fe7047..8c91794f46 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index 00980f0189..8a50ace720 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.11.0-beta.2 + sentry: 9.11.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index 1aee4167bc..cb7dc8dd6d 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0-beta.2'; +const String sdkVersion = '9.11.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index ed3aed21c8..4bbbf5d7de 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.11.0-beta.2 + sentry: 9.11.0 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 5bb9259dab..84b07fff79 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.11.0-beta.2 +version: 9.11.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: http: ^1.3.0 meta: ^1.3.0 - sentry: 9.11.0-beta.2 + sentry: 9.11.0 dev_dependencies: supabase: ^2.6.0 From 15eee808443cedf294dec09ff2a1e4f0a70cc7fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:39:50 +0100 Subject: [PATCH 41/62] chore: update packages/flutter/scripts/update-native.sh to 0.12.5 (#3481) Co-authored-by: GitHub --- CHANGELOG.md | 8 ++++++++ packages/flutter/sentry-native/CMakeCache.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27bb967225..4f97d9c571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Dependencies + +- Bump Native SDK from v0.12.3 to v0.12.5 ([#3481](https://github.com/getsentry/sentry-dart/pull/3481)) + - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0125) + - [diff](https://github.com/getsentry/sentry-native/compare/0.12.3...0.12.5) + ## 9.11.0 ### Features diff --git a/packages/flutter/sentry-native/CMakeCache.txt b/packages/flutter/sentry-native/CMakeCache.txt index dba0a16109..e6ee1ebd77 100644 --- a/packages/flutter/sentry-native/CMakeCache.txt +++ b/packages/flutter/sentry-native/CMakeCache.txt @@ -2,4 +2,4 @@ # Basically, this is a properties file we use both in CMake and update-deps.yml to update dependencies. repo=https://github.com/getsentry/sentry-native -version=0.12.3 +version=0.12.5 From 8bfae646cde8932cbc444e56097acb3730dd0baa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 17:57:18 +0100 Subject: [PATCH 42/62] chore: update packages/flutter/scripts/update-android.sh to 8.31.0 (#3476) Co-authored-by: GitHub --- CHANGELOG.md | 3 +++ packages/flutter/android/build.gradle | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f97d9c571..871e50f202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ - Bump Native SDK from v0.12.3 to v0.12.5 ([#3481](https://github.com/getsentry/sentry-dart/pull/3481)) - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0125) - [diff](https://github.com/getsentry/sentry-native/compare/0.12.3...0.12.5) +- Bump Android SDK from v8.30.0 to v8.31.0 ([#3476](https://github.com/getsentry/sentry-dart/pull/3476)) + - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8310) + - [diff](https://github.com/getsentry/sentry-java/compare/8.30.0...8.31.0) ## 9.11.0 diff --git a/packages/flutter/android/build.gradle b/packages/flutter/android/build.gradle index 59dcf88099..4ada5d996f 100644 --- a/packages/flutter/android/build.gradle +++ b/packages/flutter/android/build.gradle @@ -62,7 +62,7 @@ android { } dependencies { - api 'io.sentry:sentry-android:8.30.0' + api 'io.sentry:sentry-android:8.31.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Required -- JUnit 4 framework From 78a22ee720a6fc0498bbef6db119cdbec0f084a6 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 5 Feb 2026 14:53:42 +0000 Subject: [PATCH 43/62] release: 9.12.0 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 871e50f202..8f53f26632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.12.0 ### Dependencies diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index 9a970445b7..77c2310a62 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.12.0 | 8.31.0 | 8.56.2 | 10.6.0 | 0.12.5 | | 9.11.0 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.2 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.1 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index cf7fbb03e9..2cfbd14625 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 1ca6e9f365..06d96fc61d 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.11.0 +version: 9.12.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index 4114a528cd..ae74e815ec 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index 3a70f6c181..522db4cf23 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.11.0 + sentry: 9.12.0 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index f6609e9fa4..a49d5d08e9 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 1438dae8d9..11b6cf26d1 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0 + sentry: 9.12.0 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 82174c75bd..8a4b1e0ab0 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index 52c1dd4b6e..9ee37ba039 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.11.0 + sentry: 9.12.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index 2e9d88d122..21a24123e3 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.11.0 + sentry: 9.12.0 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index a514371bfa..48eb0e4f00 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.11.0 +version: 9.12.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 39b905dcb3..54b8ba31b9 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 665fe9d1e4..8ea4130542 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.11.0 +version: 9.12.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.11.0 + sentry: 9.12.0 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index cd3ad92c9f..fdb6bab603 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index 48e399d6e8..a4e27b790a 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.11.0 + sentry: 9.12.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index 302cb54830..fb5bd58f3c 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index 5b51961113..7f6b8e933d 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.11.0 + sentry: 9.12.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index 458126af10..c1b66a78ce 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.11.0 + sentry: 9.12.0 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index 8c91794f46..bce6385477 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index 8a50ace720..ca3b63b822 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.11.0 + sentry: 9.12.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index cb7dc8dd6d..e78344c143 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.11.0'; +const String sdkVersion = '9.12.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index 4bbbf5d7de..f0c64353f9 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.11.0 + sentry: 9.12.0 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 84b07fff79..cdef236c7d 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.11.0 +version: 9.12.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: http: ^1.3.0 meta: ^1.3.0 - sentry: 9.11.0 + sentry: 9.12.0 dev_dependencies: supabase: ^2.6.0 From a34fde047aced962cc6e40db0cc49cdcdc5d2fe1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:59:59 +0100 Subject: [PATCH 44/62] chore: update packages/flutter/scripts/update-js.sh to 10.38.0 (#3474) Co-authored-by: GitHub --- CHANGELOG.md | 8 ++++++++ packages/flutter/lib/src/web/sentry_js_sdk_version.dart | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f53f26632..01089dfba6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Dependencies + +- Bump JavaScript SDK from v10.6.0 to v10.38.0 ([#3474](https://github.com/getsentry/sentry-dart/pull/3474)) + - [changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#10380) + - [diff](https://github.com/getsentry/sentry-javascript/compare/10.6.0...10.38.0) + ## 9.12.0 ### Dependencies diff --git a/packages/flutter/lib/src/web/sentry_js_sdk_version.dart b/packages/flutter/lib/src/web/sentry_js_sdk_version.dart index 62fa4cd326..70279fe6c7 100644 --- a/packages/flutter/lib/src/web/sentry_js_sdk_version.dart +++ b/packages/flutter/lib/src/web/sentry_js_sdk_version.dart @@ -2,12 +2,12 @@ import 'package:meta/meta.dart'; /// DO NOT EDIT – generated by scripts/update-js.sh @internal -const sentryJsSdkVersion = '10.6.0'; +const sentryJsSdkVersion = '10.38.0'; @internal const productionIntegrity = - 'sha384-SFODEb3T2QkMjTr3S1it5zIK0cIW7jsComFUkmJ9nU9uaWs3AzA6cubt8xn0zW7A'; + 'sha384-COL1vOWQO+0hwStGhZ6r5BKlWlJzd59gOqtCYmcIvfDd0ifnTHrWzzQQYmUNf/Lr'; @internal const debugIntegrity = - 'sha384-qsi17lmgPOT3Gv8aKKWKWD2ZgR5SokLG5iV1HL6GMhpk9fqujLH7R+1R86IGXroI'; + 'sha384-9BkiiMtTHx82WK2Pxl4Y2NsqQJChBS1XQaV0yzkW/Fz3lsa8A2E2chXICFsAFFew'; From d096f79b7104616da057521f2427d85db987c027 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 12 Feb 2026 13:12:24 +0100 Subject: [PATCH 45/62] chore(bugbot): Update `BUGBOT.md` to check the PR description when reviewing dependency updates (#3509) * Update BUGBOT.md --- .cursor/BUGBOT.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.cursor/BUGBOT.md b/.cursor/BUGBOT.md index 73e21f6035..6bf65213fe 100644 --- a/.cursor/BUGBOT.md +++ b/.cursor/BUGBOT.md @@ -32,6 +32,14 @@ - **Breaking changes**: Signature/behavior changes, renamed/removed symbols, altered nullability/defaults, or event/telemetry shape changes **without** deprecation/migration notes. - **Behavioral compatibility**: Silent changes to defaults, sampling, or feature toggles that affect existing apps. +### C. Dependency Updates + +- **Native SDK updates**: For PRs prefixed with `chore(deps):` updating native SDKs (e.g., `chore(deps): update Android SDK to v8.32.0`, `chore(deps): update Cocoa SDK to v9.0.0`): + - Read the PR description which should contain the changelog. + - Review mentioned changes for potential compatibility issues in the current codebase. + - Flag breaking API changes, deprecated features being removed, new requirements, or behavioral changes that could affect existing integrations. + - Check if version bumps require corresponding changes in native bridge code, method channels, or platform-specific implementations. + --- ## 1) General Software Quality @@ -110,6 +118,7 @@ - [ ] **CRITICAL:** No secrets/PII/logging risks introduced; safe defaults preserved. - [ ] **CRITICAL:** Public API/telemetry stability maintained or properly deprecated with docs. +- [ ] **CRITICAL:** For dependency updates (`chore(deps):`), changelog reviewed for breaking changes or compatibility issues. - [ ] Spans started are always closed; automated spans/logs include `sentry.origin` (+ valid `sentry.op` for spans). - [ ] Dangerous init paths guarded; app remains usable on failure. - [ ] No `!` on nullable targets; async gaps guarded; resources disposed. From 53356d8e1592d42d65d75d0f22b9d9574cbdc12e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 14:51:59 +0100 Subject: [PATCH 46/62] chore(deps): update Android SDK to v8.32.0 (#3506) * chore: update packages/flutter/scripts/update-android.sh to 8.32.0 * Add spotlight as debugImplementation * Update analyze * Updat * Update android example sdk targets * Update --------- Co-authored-by: GitHub Co-authored-by: Giancarlo Buenaflor Co-authored-by: Giancarlo Buenaflor --- .gitignore | 1 - CHANGELOG.md | 3 ++ min_version_test/android/app/build.gradle | 4 +- packages/flutter/android/build.gradle | 7 +-- .../flutter/example/android/app/build.gradle | 4 +- .../platform_integrations_test.dart | 2 +- .../integration_test/profiling_test.dart | 4 +- .../ios/Runner.xcodeproj/project.pbxproj | 22 ++++++++ .../xcshareddata/swiftpm/Package.resolved | 22 ++++++++ .../xcshareddata/xcschemes/Runner.xcscheme | 21 ++++++++ .../xcshareddata/swiftpm/Package.resolved | 22 ++++++++ packages/flutter/example/lib/main.dart | 2 +- .../flutter/lib/src/native/java/binding.dart | 52 +++++++++++++++++++ packages/flutter/scripts/update-android.sh | 34 ++++++++---- .../native/android_envelope_sender_test.dart | 12 ++++- .../test/native/sentry_native_java_test.dart | 12 ++++- .../test/sentry_isar_collection_test.dart | 6 +-- 17 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 packages/flutter/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 packages/flutter/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/.gitignore b/.gitignore index 42cbdaf05e..c757ee039a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ build/ .cxx/ .vscode/ .fvm/ -.fvmrc .test_coverage.dart packages/**/coverage/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 01089dfba6..b5871b6734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Dependencies +- Bump Android SDK from v8.31.0 to v8.32.0 ([#3506](https://github.com/getsentry/sentry-dart/pull/3506)) + - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8320) + - [diff](https://github.com/getsentry/sentry-java/compare/8.31.0...8.32.0) - Bump JavaScript SDK from v10.6.0 to v10.38.0 ([#3474](https://github.com/getsentry/sentry-dart/pull/3474)) - [changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#10380) - [diff](https://github.com/getsentry/sentry-javascript/compare/10.6.0...10.38.0) diff --git a/min_version_test/android/app/build.gradle b/min_version_test/android/app/build.gradle index 60657193d7..13f83ce6b3 100644 --- a/min_version_test/android/app/build.gradle +++ b/min_version_test/android/app/build.gradle @@ -28,7 +28,7 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { namespace 'com.example.minversiontest' - compileSdkVersion 35 + compileSdkVersion 36 ndkVersion '21.4.7075529' compileOptions { @@ -51,7 +51,7 @@ android { // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion flutter.minSdkVersion - targetSdkVersion 35 + targetSdkVersion 36 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/flutter/android/build.gradle b/packages/flutter/android/build.gradle index 4ada5d996f..3d68acbc1a 100644 --- a/packages/flutter/android/build.gradle +++ b/packages/flutter/android/build.gradle @@ -22,7 +22,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 34 + compileSdkVersion 36 // Conditional for compatibility with AGP <4.2. if (project.android.hasProperty("namespace")) { @@ -35,7 +35,7 @@ android { defaultConfig { minSdkVersion 21 - targetSdkVersion 34 + targetSdkVersion 36 ndk { // Flutter does not currently support building for x86 Android (See Issue 9253). @@ -62,7 +62,8 @@ android { } dependencies { - api 'io.sentry:sentry-android:8.31.0' + api 'io.sentry:sentry-android:8.32.0' + debugImplementation 'io.sentry:sentry-spotlight:8.32.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Required -- JUnit 4 framework diff --git a/packages/flutter/example/android/app/build.gradle b/packages/flutter/example/android/app/build.gradle index f7d077feff..59d2dbb47d 100644 --- a/packages/flutter/example/android/app/build.gradle +++ b/packages/flutter/example/android/app/build.gradle @@ -37,7 +37,7 @@ android { languageVersion = System.getenv("KOTLIN_LANGUAGE_VERSION") ?: "1.7" } - compileSdkVersion 35 + compileSdkVersion 36 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -46,7 +46,7 @@ android { defaultConfig { applicationId "io.sentry.samples.flutter" minSdkVersion flutter.minSdkVersion - targetSdkVersion 35 + targetSdkVersion 36 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/flutter/example/integration_test/platform_integrations_test.dart b/packages/flutter/example/integration_test/platform_integrations_test.dart index a76cd94cc6..ccf2ec3af8 100644 --- a/packages/flutter/example/integration_test/platform_integrations_test.dart +++ b/packages/flutter/example/integration_test/platform_integrations_test.dart @@ -1,4 +1,4 @@ -// ignore_for_file: invalid_use_of_internal_member, depend_on_referenced_packages +// ignore_for_file: invalid_use_of_internal_member, depend_on_referenced_packages, experimental_member_use import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/flutter/example/integration_test/profiling_test.dart b/packages/flutter/example/integration_test/profiling_test.dart index 8541c3fe35..b7756e1a41 100644 --- a/packages/flutter/example/integration_test/profiling_test.dart +++ b/packages/flutter/example/integration_test/profiling_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: experimental_member_use, invalid_use_of_internal_member + import 'dart:convert'; import 'dart:io'; @@ -14,7 +16,6 @@ void main() { Future setupSentryAndApp(WidgetTester tester) async { await SentryFlutter.init((options) { - // ignore: invalid_use_of_internal_member options.automatedTestMode = true; options.dsn = 'https://abc@def.ingest.sentry.io/1234567'; options.debug = true; @@ -33,7 +34,6 @@ void main() { testWidgets('native binding is initialized', (tester) async { await setupSentryAndApp(tester); - // ignore: invalid_use_of_internal_member expect(SentryFlutter.native, isNotNull); }); diff --git a/packages/flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/flutter/example/ios/Runner.xcodeproj/project.pbxproj index b49a8c5ccb..8db4f821b8 100644 --- a/packages/flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -69,6 +70,7 @@ C4B1A3E5A486E474A287B9BF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F2579A3BD1D48D0BC33E4ADF /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; FDFDFB8E5235EA47CE65FBC5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -84,6 +86,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, 4DFA0D3B754F0E702B3CB4B1 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -115,6 +118,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -194,6 +198,9 @@ productType = "com.apple.product-type.bundle.unit-test"; }; 97C146ED1CF9000F007C117D /* Runner */ = { + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( @@ -219,6 +226,9 @@ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; @@ -793,6 +803,18 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/packages/flutter/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/packages/flutter/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..b248e54855 --- /dev/null +++ b/packages/flutter/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,22 @@ +{ + "pins" : [ + { + "identity" : "csqlite", + "kind" : "remoteSourceControl", + "location" : "https://github.com/simolus3/CSQLite.git", + "state" : { + "revision" : "ae972b235e8b3c5af6d8f4e5bf18c800bdddb27e" + } + }, + { + "identity" : "sentry-cocoa", + "kind" : "remoteSourceControl", + "location" : "https://github.com/getsentry/sentry-cocoa", + "state" : { + "revision" : "9e193ac0b71760603aa666bad7e9e303dd7031a8", + "version" : "8.56.2" + } + } + ], + "version" : 2 +} diff --git a/packages/flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fee8e19903..203ce32d54 100644 --- a/packages/flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + diff --git a/packages/flutter/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/packages/flutter/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000000..b248e54855 --- /dev/null +++ b/packages/flutter/example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,22 @@ +{ + "pins" : [ + { + "identity" : "csqlite", + "kind" : "remoteSourceControl", + "location" : "https://github.com/simolus3/CSQLite.git", + "state" : { + "revision" : "ae972b235e8b3c5af6d8f4e5bf18c800bdddb27e" + } + }, + { + "identity" : "sentry-cocoa", + "kind" : "remoteSourceControl", + "location" : "https://github.com/getsentry/sentry-cocoa", + "state" : { + "revision" : "9e193ac0b71760603aa666bad7e9e303dd7031a8", + "version" : "8.56.2" + } + } + ], + "version" : 2 +} diff --git a/packages/flutter/example/lib/main.dart b/packages/flutter/example/lib/main.dart index fc73988b02..7f65a7f9c2 100644 --- a/packages/flutter/example/lib/main.dart +++ b/packages/flutter/example/lib/main.dart @@ -1,4 +1,4 @@ -// ignore_for_file: library_private_types_in_public_api +// ignore_for_file: library_private_types_in_public_api, experimental_member_use import 'dart:async'; import 'dart:convert'; diff --git a/packages/flutter/lib/src/native/java/binding.dart b/packages/flutter/lib/src/native/java/binding.dart index 5a4868e3dd..fab00f2e94 100644 --- a/packages/flutter/lib/src/native/java/binding.dart +++ b/packages/flutter/lib/src/native/java/binding.dart @@ -18167,6 +18167,58 @@ class SentryOptions extends jni$_.JObject { .check(); } + static final _id_isEnableDatabaseTransactionTracing = _class.instanceMethodId( + r'isEnableDatabaseTransactionTracing', + r'()Z', + ); + + static final _isEnableDatabaseTransactionTracing = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isEnableDatabaseTransactionTracing()` + bool isEnableDatabaseTransactionTracing() { + return _isEnableDatabaseTransactionTracing(reference.pointer, + _id_isEnableDatabaseTransactionTracing as jni$_.JMethodIDPtr) + .boolean; + } + + static final _id_setEnableDatabaseTransactionTracing = + _class.instanceMethodId( + r'setEnableDatabaseTransactionTracing', + r'(Z)V', + ); + + static final _setEnableDatabaseTransactionTracing = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setEnableDatabaseTransactionTracing(boolean z)` + void setEnableDatabaseTransactionTracing( + bool z, + ) { + _setEnableDatabaseTransactionTracing( + reference.pointer, + _id_setEnableDatabaseTransactionTracing as jni$_.JMethodIDPtr, + z ? 1 : 0) + .check(); + } + static final _id_isEnabled = _class.instanceMethodId( r'isEnabled', r'()Z', diff --git a/packages/flutter/scripts/update-android.sh b/packages/flutter/scripts/update-android.sh index 875c7e5311..c6fd0d4578 100755 --- a/packages/flutter/scripts/update-android.sh +++ b/packages/flutter/scripts/update-android.sh @@ -2,11 +2,15 @@ set -euo pipefail cd $(dirname "$0")/../android -file='build.gradle' -content=$(cat $file) -regex='(io\.sentry:sentry-android:)([0-9\.]+(\-[a-z0-9\.]+)?)' -if ! [[ $content =~ $regex ]]; then - echo "Failed to find the android plugin version in $file" +build_gradle='build.gradle' +content=$(cat $build_gradle) + +# Regex patterns for Sentry dependencies (both use the same version) +sentry_android_regex='(io\.sentry:sentry-android:)([0-9\.]+(\-[a-z0-9\.]+)?)' +sentry_spotlight_regex='(io\.sentry:sentry-spotlight:)([0-9\.]+(\-[a-z0-9\.]+)?)' + +if ! [[ $content =~ $sentry_android_regex ]]; then + echo "Failed to find the android plugin version in $build_gradle" exit 1 fi @@ -18,10 +22,22 @@ get-repo) echo "https://github.com/getsentry/sentry-java.git" ;; set-version) - newValue="${BASH_REMATCH[1]}$2" - echo "${content/${BASH_REMATCH[0]}/$newValue}" >$file - # Regenerate Dart JNI bindings so they stay in sync with the updated Android SDK version. - ../scripts/generate-jni-bindings.sh "$2" + new_version="$2" + + # Update sentry-android + new_android_dependency="${BASH_REMATCH[1]}$new_version" + content="${content/${BASH_REMATCH[0]}/$new_android_dependency}" + + # Update sentry-spotlight to match the same version (if present) + if [[ $content =~ $sentry_spotlight_regex ]]; then + new_spotlight_dependency="${BASH_REMATCH[1]}$new_version" + content="${content/${BASH_REMATCH[0]}/$new_spotlight_dependency}" + fi + + echo "$content" >$build_gradle + + # Regenerate Dart JNI bindings so they stay in sync with the updated Android SDK version + ../scripts/generate-jni-bindings.sh "$new_version" ;; *) echo "Unknown argument $1" diff --git a/packages/flutter/test/native/android_envelope_sender_test.dart b/packages/flutter/test/native/android_envelope_sender_test.dart index 9779018acb..f66a7063f2 100644 --- a/packages/flutter/test/native/android_envelope_sender_test.dart +++ b/packages/flutter/test/native/android_envelope_sender_test.dart @@ -1,2 +1,10 @@ -export 'android_envelope_sender_test_real.dart' - if (dart.library.js_interop) 'android_envelope_sender_test_web.dart'; +@TestOn('vm') +library; + +import 'package:flutter_test/flutter_test.dart'; + +// ignore: unused_import +import 'android_envelope_sender_test_web.dart' + if (dart.library.io) 'android_envelope_sender_test_real.dart' as actual; + +void main() => actual.main(); diff --git a/packages/flutter/test/native/sentry_native_java_test.dart b/packages/flutter/test/native/sentry_native_java_test.dart index 5e6285f1b0..db711f8568 100644 --- a/packages/flutter/test/native/sentry_native_java_test.dart +++ b/packages/flutter/test/native/sentry_native_java_test.dart @@ -1,2 +1,10 @@ -export 'sentry_native_java_test_real.dart' - if (dart.library.js_interop) 'sentry_native_java_test_web.dart'; +@TestOn('vm') +library; + +import 'package:flutter_test/flutter_test.dart'; + +// ignore: unused_import +import 'sentry_native_java_test_web.dart' + if (dart.library.io) 'sentry_native_java_test_real.dart' as actual; + +void main() => actual.main(); diff --git a/packages/isar/test/sentry_isar_collection_test.dart b/packages/isar/test/sentry_isar_collection_test.dart index 197c74e4e4..83b27a344c 100644 --- a/packages/isar/test/sentry_isar_collection_test.dart +++ b/packages/isar/test/sentry_isar_collection_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: experimental_member_use, invalid_use_of_internal_member, invalid_use_of_protected_member + import 'dart:io'; import 'dart:typed_data'; @@ -22,7 +24,6 @@ void main() { expect(span?.context.operation, SentryIsar.dbOp); expect(span?.context.description, description); expect(span?.status, SpanStatus.ok()); - // ignore: invalid_use_of_internal_member expect(span?.origin, SentryTraceOrigins.autoDbIsarCollection); expect(span?.data[SentryIsar.dbNameKey], Fixture.dbName); expect(span?.data[SentryIsar.dbCollectionKey], 'Person'); @@ -32,7 +33,6 @@ void main() { expect(span?.context.operation, SentryIsar.dbOp); expect(span?.context.description, description); expect(span?.status, SpanStatus.internalError()); - // ignore: invalid_use_of_internal_member expect(span?.origin, SentryTraceOrigins.autoDbIsarCollection); expect(span?.throwable, error); } @@ -243,7 +243,6 @@ void main() { expect(span?.context.operation, SentryIsar.dbOp); expect(span?.context.description, description); expect(span?.status, SpanStatus.ok()); - // ignore: invalid_use_of_internal_member expect(span?.origin, SentryTraceOrigins.autoDbIsarCollection); expect(span?.data[SentryIsar.dbNameKey], Fixture.dbName); expect(span?.data[SentryIsar.dbCollectionKey], Fixture.dbCollection); @@ -970,7 +969,6 @@ class Fixture { Future tearDown() async { try { - // ignore: invalid_use_of_protected_member sentryIsar.requireOpen(); await sentryIsar.close(); } catch (_) { From 4e1411338de17f7b13d485c480a466f9d3e7228b Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 12 Feb 2026 17:29:33 +0100 Subject: [PATCH 47/62] feat(flutter): Synchronize `traceId` to native SDKs (#3507) * feat: Synchronize PropagationContext to native SDKs (#3406) Native crashes/errors on Android and iOS carry their own independently- generated traceId, disconnecting them from the Dart-side trace. This wires up the existing native setTrace APIs so the Dart PropagationContext is synced to native on init and whenever generateNewTrace() is called. - Add OnTraceReset lifecycle event dispatched from Hub.generateNewTrace() - Add NativeTraceSyncIntegration that subscribes to OnTraceReset and calls the platform-specific native setTrace API - Implement setTrace on all platform bindings (JNI for Android, method channel for Cocoa, no-op for C/Web) - Add supportsTraceSync capability flag to SentryNativeBinding - Disable native auto trace ID generation on Android so Flutter is the single source of truth - Add setTrace handler in iOS SentryFlutterPlugin.swift - Register NativeTraceSyncIntegration in default integrations Co-Authored-By: Claude Opus 4.6 * Fix build * Update CHANGELOG * Update * Update * Update * Update * Fix mocks * Update * Update doc * Fix changelog * Update * Review * Update * Bubble up error from native flutter plugin in swift * Move enableNativeTraceSync from dart to flutter options * Fix duplicate result * Improve documentation --------- Co-authored-by: Claude Opus 4.6 --- CHANGELOG.md | 5 + packages/dart/lib/src/hub.dart | 7 +- .../dart/lib/src/propagation_context.dart | 2 +- .../dart/lib/src/sdk_lifecycle_hooks.dart | 9 + packages/dart/test/hub_test.dart | 62 ++++ .../dart/test/propagation_context_test.dart | 2 +- .../integration_test/integration_test.dart | 38 +++ packages/flutter/ffi-jni.yaml | 1 + .../sentry_flutter/SentryFlutterPlugin.swift | 18 ++ .../native_trace_sync_integration.dart | 46 +++ .../lib/src/native/c/sentry_native.dart | 8 + .../flutter/lib/src/native/java/binding.dart | 300 +++++++++++++++++- .../src/native/java/sentry_native_java.dart | 20 ++ .../native/java/sentry_native_java_init.dart | 6 + .../lib/src/native/sentry_native_binding.dart | 6 + .../lib/src/native/sentry_native_channel.dart | 17 + packages/flutter/lib/src/sentry_flutter.dart | 4 + .../lib/src/sentry_flutter_options.dart | 7 + packages/flutter/lib/src/web/sentry_web.dart | 8 + .../native_trace_sync_integration_test.dart | 101 ++++++ packages/flutter/test/mocks.dart | 1 + packages/flutter/test/mocks.mocks.dart | 106 ++++--- 22 files changed, 723 insertions(+), 51 deletions(-) create mode 100644 packages/flutter/lib/src/integrations/native_trace_sync_integration.dart create mode 100644 packages/flutter/test/integrations/native_trace_sync_integration_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index b5871b6734..4caf809621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Features + +- Synchronize `traceId` to native SDKs ([#3507](https://github.com/getsentry/sentry-dart/pull/3507)) + - Native events (e.g. from Android or iOS) such as errors, logs, and spans now share the same trace as Dart events, enabling unified trace views across layers + ### Dependencies - Bump Android SDK from v8.31.0 to v8.32.0 ([#3506](https://github.com/getsentry/sentry-dart/pull/3506)) diff --git a/packages/dart/lib/src/hub.dart b/packages/dart/lib/src/hub.dart index 8ffc57d15b..77a1c8581e 100644 --- a/packages/dart/lib/src/hub.dart +++ b/packages/dart/lib/src/hub.dart @@ -609,7 +609,12 @@ class Hub { void generateNewTrace() { // Create a brand-new trace and reset the sampling flag and sampleRand so // that the next root transaction can set it again. - scope.propagationContext.resetTrace(); + scope.propagationContext.generateNewTrace(); + // Fire-and-forget the callback + // Native SDK synchronization over async method channels may be slightly delayed, but this is not problematic in practice. + _options.lifecycleRegistry.dispatchCallback(OnGenerateNewTrace( + scope.propagationContext.traceId, + getSpan()?.context.spanId ?? SpanId.newId())); } /// Gets the current active transaction or span. diff --git a/packages/dart/lib/src/propagation_context.dart b/packages/dart/lib/src/propagation_context.dart index b75a897383..167bf761be 100644 --- a/packages/dart/lib/src/propagation_context.dart +++ b/packages/dart/lib/src/propagation_context.dart @@ -39,7 +39,7 @@ class PropagationContext { double? sampleRand; /// Starts a brand-new trace (new ID, new sampling value & sampled state). - void resetTrace() { + void generateNewTrace() { traceId = SentryId.newId(); sampleRand = null; _sampled = null; diff --git a/packages/dart/lib/src/sdk_lifecycle_hooks.dart b/packages/dart/lib/src/sdk_lifecycle_hooks.dart index 36912dc523..219e8ff49d 100644 --- a/packages/dart/lib/src/sdk_lifecycle_hooks.dart +++ b/packages/dart/lib/src/sdk_lifecycle_hooks.dart @@ -103,3 +103,12 @@ class OnProcessMetric extends SdkLifecycleEvent { OnProcessMetric(this.metric); } + +/// Dispatched when a new trace is generated via [Hub.generateNewTrace]. +@internal +class OnGenerateNewTrace extends SdkLifecycleEvent { + final SentryId traceId; + final SpanId spanId; + + OnGenerateNewTrace(this.traceId, this.spanId); +} diff --git a/packages/dart/test/hub_test.dart b/packages/dart/test/hub_test.dart index a5dcc6e1c5..475e057497 100644 --- a/packages/dart/test/hub_test.dart +++ b/packages/dart/test/hub_test.dart @@ -637,6 +637,68 @@ void main() { final newSampleRand = hub.scope.propagationContext.sampleRand; expect(newSampleRand, isNull); }); + + test('generateNewTrace dispatches OnTraceReset with traceId', () { + SentryId? receivedTraceId; + hub.options.lifecycleRegistry + .registerCallback((event) { + receivedTraceId = event.traceId; + }); + + hub.generateNewTrace(); + + expect(receivedTraceId, isNotNull); + expect(receivedTraceId, hub.scope.propagationContext.traceId); + }); + + test( + 'generateNewTrace dispatches OnTraceReset with spanId from active span', + () { + SpanId? receivedSpanId; + hub.options.tracesSampleRate = 1.0; + hub.options.lifecycleRegistry + .registerCallback((event) { + receivedSpanId = event.spanId; + }); + + hub.startTransaction('name', 'op', bindToScope: true); + hub.generateNewTrace(); + + expect(receivedSpanId, isNotNull); + expect(receivedSpanId, hub.getSpan()?.context.spanId); + }); + + test( + 'generateNewTrace dispatches OnTraceReset with new spanId if no active span', + () { + SpanId? receivedSpanId; + hub.options.tracesSampleRate = 1.0; + hub.options.lifecycleRegistry + .registerCallback((event) { + receivedSpanId = event.spanId; + }); + + hub.generateNewTrace(); + + expect(hub.getSpan(), isNull); + expect(receivedSpanId, isNotNull); + }); + + test( + 'generateNewTrace dispatches OnTraceReset with new spanId if tracing is disabled', + () { + SpanId? receivedSpanId; + hub.options.tracesSampleRate = null; + hub.options.lifecycleRegistry + .registerCallback((event) { + receivedSpanId = event.spanId; + }); + + hub.generateNewTrace(); + + expect(hub.getSpan(), isNull); + expect(receivedSpanId, isNotNull); + }); }); group('Hub scope callback', () { diff --git a/packages/dart/test/propagation_context_test.dart b/packages/dart/test/propagation_context_test.dart index 22347faa3a..7f128728ab 100644 --- a/packages/dart/test/propagation_context_test.dart +++ b/packages/dart/test/propagation_context_test.dart @@ -126,7 +126,7 @@ void main() { sut.sampleRand = 1.0; sut.applySamplingDecision(true); - sut.resetTrace(); + sut.generateNewTrace(); expect(sut.traceId, isNot(traceId)); expect(sut.sampleRand, isNull); diff --git a/packages/flutter/example/integration_test/integration_test.dart b/packages/flutter/example/integration_test/integration_test.dart index 4d7f9dce72..787f47a80a 100644 --- a/packages/flutter/example/integration_test/integration_test.dart +++ b/packages/flutter/example/integration_test/integration_test.dart @@ -279,6 +279,7 @@ void main() { (p) => p.name == package.name && p.version == package.version); expect(findMatchingPackage, isNotNull); } + expect(androidOptions.isEnableAutoTraceIdGeneration(), isFalse); final androidProxy = androidOptions.getProxy(); expect(androidProxy, isNotNull); expect(androidProxy!.getHost()?.toDartString(), 'proxy.local'); @@ -1065,6 +1066,43 @@ void main() { } }); + // We currently only test this on Android + // Setting up iOS for testing this is a big time effort so we rely on manually testing there for now + testWidgets('setTrace syncs Dart traceId to native Android scope', + (tester) async { + await restoreFlutterOnErrorAfter(() async { + await setupSentryAndApp(tester); + }); + + final dartTraceId = + Sentry.currentHub.scope.propagationContext.traceId.toString(); + + final traceParent = jni.Sentry.getTraceparent(); + expect(traceParent, isNotNull, + reason: 'Native traceparent should not be null'); + final traceHeader = traceParent!.getValue().toDartString(); + + final nativeTraceId = traceHeader.split('-').first; + expect(nativeTraceId, dartTraceId, + reason: 'Native traceId should match Dart traceId after initial sync'); + + Sentry.currentHub.generateNewTrace(); + final newDartTraceId = + Sentry.currentHub.scope.propagationContext.traceId.toString(); + + // Allow the fire-and-forget dispatch to complete + await Future.delayed(const Duration(milliseconds: 100)); + + final newTraceParent = + jni.Sentry.getTraceparent()?.getValue().toDartString(); + final newTraceHeader = newTraceParent!.toString(); + + final newNativeTraceId = newTraceHeader.split('-').first; + expect(newNativeTraceId, newDartTraceId, + reason: + 'Native traceId should match new Dart traceId after generateNewTrace'); + }, skip: !Platform.isAndroid); + group('e2e', () { var output = find.byKey(const Key('output')); late Fixture fixture; diff --git a/packages/flutter/ffi-jni.yaml b/packages/flutter/ffi-jni.yaml index 2a12b989c2..4a7a804a65 100644 --- a/packages/flutter/ffi-jni.yaml +++ b/packages/flutter/ffi-jni.yaml @@ -40,6 +40,7 @@ classes: - io.sentry.protocol.SentryPackage - io.sentry.rrweb.RRWebOptionsEvent - io.sentry.rrweb.RRWebEvent + - io.sentry.SentryTraceHeader - java.net.Proxy - android.graphics.Bitmap - android.content.Context 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 e2b370d29e..a894c8daf5 100644 --- a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift +++ b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -161,6 +161,12 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { result(nil) #endif + case "setTrace": + let arguments = call.arguments as? [String: Any?] + let traceId = arguments?["traceId"] as? String + let spanId = arguments?["spanId"] as? String + setTrace(traceId: traceId, spanId: spanId, result: result) + default: result(FlutterMethodNotImplemented) } @@ -696,6 +702,18 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { result("") } + private func setTrace(traceId: String?, spanId: String?, result: @escaping FlutterResult) { + guard let traceId = traceId, let spanId = spanId else { + print("Cannot set trace: traceId or spanId is null") + result(FlutterError(code: "10", message: "Cannot set trace: traceId or spanId is null", details: nil)) + return + } + let sentryTraceId = SentryId(uuidString: traceId) + let sentrySpanId = SpanId(value: spanId) + PrivateSentrySDKOnly.setTrace(sentryTraceId, spanId: sentrySpanId) + result("") + } + private func crash() { SentrySDK.crash() } diff --git a/packages/flutter/lib/src/integrations/native_trace_sync_integration.dart b/packages/flutter/lib/src/integrations/native_trace_sync_integration.dart new file mode 100644 index 0000000000..53308cb348 --- /dev/null +++ b/packages/flutter/lib/src/integrations/native_trace_sync_integration.dart @@ -0,0 +1,46 @@ +// ignore_for_file: invalid_use_of_internal_member + +import 'dart:async'; + +import 'package:meta/meta.dart'; + +import '../../sentry_flutter.dart'; +import '../native/sentry_native_binding.dart'; +import '../utils/internal_logger.dart'; + +@internal +class NativeTraceSyncIntegration implements Integration { + static const integrationName = 'NativeTraceSync'; + final SentryNativeBinding _native; + SentryOptions? _options; + + NativeTraceSyncIntegration(this._native); + + @override + void call(Hub hub, SentryFlutterOptions options) { + if (!options.enableNativeTraceSync) { + internalLogger.info('$integrationName: disabled, skipping setup'); + return; + } + + _options = options; + options.lifecycleRegistry + .registerCallback(_syncTraceToNative); + options.sdk.addIntegration(integrationName); + + final traceId = hub.scope.propagationContext.traceId; + final spanId = hub.getSpan()?.context.spanId ?? SpanId.newId(); + + // Sync the initial PropagationContext created at Hub construction. + _syncTraceToNative(OnGenerateNewTrace(traceId, spanId)); + } + + @override + void close() { + _options?.lifecycleRegistry + .removeCallback(_syncTraceToNative); + } + + FutureOr _syncTraceToNative(OnGenerateNewTrace event) => + _native.setTrace(event.traceId, event.spanId); +} diff --git a/packages/flutter/lib/src/native/c/sentry_native.dart b/packages/flutter/lib/src/native/c/sentry_native.dart index 85c0b602c6..1d082cd6d9 100644 --- a/packages/flutter/lib/src/native/c/sentry_native.dart +++ b/packages/flutter/lib/src/native/c/sentry_native.dart @@ -310,6 +310,14 @@ class SentryNative with SentryNativeSafeInvoker implements SentryNativeBinding { FutureOr updateSession({int? errors, String? status}) { _logNotSupported('updating session'); } + + @override + bool get supportsTraceSync => false; + + @override + FutureOr setTrace(SentryId traceId, SpanId spanId) { + _logNotSupported('setting trace'); + } } extension on binding.sentry_value_u { diff --git a/packages/flutter/lib/src/native/java/binding.dart b/packages/flutter/lib/src/native/java/binding.dart index fab00f2e94..249a58c6ac 100644 --- a/packages/flutter/lib/src/native/java/binding.dart +++ b/packages/flutter/lib/src/native/java/binding.dart @@ -8181,10 +8181,10 @@ class Sentry extends jni$_.JObject { /// from: `static public io.sentry.SentryTraceHeader getTraceparent()` /// The returned object must be released after use, by calling the [release] method. - static jni$_.JObject? getTraceparent() { + static SentryTraceHeader? getTraceparent() { return _getTraceparent( _class.reference.pointer, _id_getTraceparent as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + .object(const $SentryTraceHeader$NullableType()); } static final _id_getBaggage = _class.staticMethodId( @@ -31510,10 +31510,10 @@ class ScopesAdapter extends jni$_.JObject { /// from: `public io.sentry.SentryTraceHeader getTraceparent()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getTraceparent() { + SentryTraceHeader? getTraceparent() { return _getTraceparent( reference.pointer, _id_getTraceparent as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + .object(const $SentryTraceHeader$NullableType()); } static final _id_getBaggage = _class.instanceMethodId( @@ -38704,6 +38704,298 @@ final class $RRWebEvent$Type extends jni$_.JObjType { } } +/// from: `io.sentry.SentryTraceHeader` +class SentryTraceHeader extends jni$_.JObject { + @jni$_.internal + @core$_.override + final jni$_.JObjType $type; + + @jni$_.internal + SentryTraceHeader.fromReference( + jni$_.JReference reference, + ) : $type = type, + super.fromReference(reference); + + static final _class = jni$_.JClass.forName(r'io/sentry/SentryTraceHeader'); + + /// The type which includes information such as the signature of this class. + static const nullableType = $SentryTraceHeader$NullableType(); + static const type = $SentryTraceHeader$Type(); + static final _id_SENTRY_TRACE_HEADER = _class.staticFieldId( + r'SENTRY_TRACE_HEADER', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String SENTRY_TRACE_HEADER` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get SENTRY_TRACE_HEADER => + _id_SENTRY_TRACE_HEADER.get(_class, const jni$_.JStringNullableType()); + + static final _id_new$ = _class.constructorId( + r'(Lio/sentry/protocol/SentryId;Lio/sentry/SpanId;Ljava/lang/Boolean;)V', + ); + + static final _new$ = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_NewObject') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `public void (io.sentry.protocol.SentryId sentryId, io.sentry.SpanId spanId, java.lang.Boolean boolean)` + /// The returned object must be released after use, by calling the [release] method. + factory SentryTraceHeader( + SentryId sentryId, + jni$_.JObject spanId, + jni$_.JBoolean? boolean, + ) { + final _$sentryId = sentryId.reference; + final _$spanId = spanId.reference; + final _$boolean = boolean?.reference ?? jni$_.jNullReference; + return SentryTraceHeader.fromReference(_new$( + _class.reference.pointer, + _id_new$ as jni$_.JMethodIDPtr, + _$sentryId.pointer, + _$spanId.pointer, + _$boolean.pointer) + .reference); + } + + static final _id_new$1 = _class.constructorId( + r'(Ljava/lang/String;)V', + ); + + static final _new$1 = 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 (java.lang.String string)` + /// The returned object must be released after use, by calling the [release] method. + factory SentryTraceHeader.new$1( + jni$_.JString string, + ) { + final _$string = string.reference; + return SentryTraceHeader.fromReference(_new$1(_class.reference.pointer, + _id_new$1 as jni$_.JMethodIDPtr, _$string.pointer) + .reference); + } + + static final _id_getName = _class.instanceMethodId( + r'getName', + r'()Ljava/lang/String;', + ); + + static final _getName = 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 getName()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString getName() { + return _getName(reference.pointer, _id_getName as jni$_.JMethodIDPtr) + .object(const jni$_.JStringType()); + } + + static final _id_getValue = _class.instanceMethodId( + r'getValue', + r'()Ljava/lang/String;', + ); + + static final _getValue = 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 getValue()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString getValue() { + return _getValue(reference.pointer, _id_getValue as jni$_.JMethodIDPtr) + .object(const jni$_.JStringType()); + } + + static final _id_getTraceId = _class.instanceMethodId( + r'getTraceId', + r'()Lio/sentry/protocol/SentryId;', + ); + + static final _getTraceId = 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 getTraceId()` + /// The returned object must be released after use, by calling the [release] method. + SentryId getTraceId() { + return _getTraceId(reference.pointer, _id_getTraceId as jni$_.JMethodIDPtr) + .object(const $SentryId$Type()); + } + + static final _id_getSpanId = _class.instanceMethodId( + r'getSpanId', + r'()Lio/sentry/SpanId;', + ); + + static final _getSpanId = 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.SpanId getSpanId()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject getSpanId() { + return _getSpanId(reference.pointer, _id_getSpanId as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectType()); + } + + static final _id_isSampled = _class.instanceMethodId( + r'isSampled', + r'()Ljava/lang/Boolean;', + ); + + static final _isSampled = 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.Boolean isSampled()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JBoolean? isSampled() { + return _isSampled(reference.pointer, _id_isSampled as jni$_.JMethodIDPtr) + .object(const jni$_.JBooleanNullableType()); + } +} + +final class $SentryTraceHeader$NullableType + extends jni$_.JObjType { + @jni$_.internal + const $SentryTraceHeader$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/SentryTraceHeader;'; + + @jni$_.internal + @core$_.override + SentryTraceHeader? fromReference(jni$_.JReference reference) => + reference.isNull + ? null + : SentryTraceHeader.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 => ($SentryTraceHeader$NullableType).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($SentryTraceHeader$NullableType) && + other is $SentryTraceHeader$NullableType; + } +} + +final class $SentryTraceHeader$Type extends jni$_.JObjType { + @jni$_.internal + const $SentryTraceHeader$Type(); + + @jni$_.internal + @core$_.override + String get signature => r'Lio/sentry/SentryTraceHeader;'; + + @jni$_.internal + @core$_.override + SentryTraceHeader fromReference(jni$_.JReference reference) => + SentryTraceHeader.fromReference( + reference, + ); + @jni$_.internal + @core$_.override + jni$_.JObjType get superType => const jni$_.JObjectNullableType(); + + @jni$_.internal + @core$_.override + jni$_.JObjType get nullableType => + const $SentryTraceHeader$NullableType(); + + @jni$_.internal + @core$_.override + final superCount = 1; + + @core$_.override + int get hashCode => ($SentryTraceHeader$Type).hashCode; + + @core$_.override + bool operator ==(Object other) { + return other.runtimeType == ($SentryTraceHeader$Type) && + other is $SentryTraceHeader$Type; + } +} + /// from: `java.net.Proxy$Type` class Proxy$Type 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 5f56f35040..a57ea31a47 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java.dart @@ -388,6 +388,26 @@ class SentryNativeJava extends SentryNativeChannel { replayConfig.release(); }); + + @override + bool get supportsTraceSync => true; + + @override + void setTrace(SentryId traceId, SpanId spanId) { + tryCatchSync('setTrace', () { + using((arena) { + final jTraceId = traceId.toString().toJString()..releasedBy(arena); + final jSpanId = spanId.toString().toJString()..releasedBy(arena); + // The two double parameters are sampleRate and sampleRand. + // We pass null for them because we don't need to support sampleRate and sampleRand. + // sampleRate and sampleRand are only used by native for baggage headers + // on outgoing HTTP requests. Since HTTP requests in Flutter go through + // Dart, the Dart-side propagation context handles baggage already. + // When there is a use case for sampleRate and sampleRand, we can add support for them. + native.InternalSentrySdk.setTrace(jTraceId, jSpanId, null, null); + }); + }); + } } @visibleForTesting diff --git a/packages/flutter/lib/src/native/java/sentry_native_java_init.dart b/packages/flutter/lib/src/native/java/sentry_native_java_init.dart index 98af364019..86004d5bc3 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java_init.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java_init.dart @@ -239,6 +239,12 @@ void configureAndroidOptions({ } androidOptions.setSendDefaultPii(options.sendDefaultPii); androidOptions.setEnableScopeSync(options.enableNdkScopeSync); + // When trace sync is enabled, Dart is the source of truth for propagation + // context and pushes it to native via setTrace. Disable native auto + // generation so it doesn't overwrite the Dart-provided trace ID. + if (options.enableNativeTraceSync) { + androidOptions.setEnableAutoTraceIdGeneration(false); + } androidOptions .setProguardUuid(options.proguardUuid?.toJString()?..releasedBy(arena)); androidOptions.setEnableSpotlight(options.spotlight.enabled); diff --git a/packages/flutter/lib/src/native/sentry_native_binding.dart b/packages/flutter/lib/src/native/sentry_native_binding.dart index bf45423d25..1efd177fe1 100644 --- a/packages/flutter/lib/src/native/sentry_native_binding.dart +++ b/packages/flutter/lib/src/native/sentry_native_binding.dart @@ -93,4 +93,10 @@ abstract class SentryNativeBinding { /// /// NNote: This is used on web platforms and is a no-op on non-web. FutureOr captureSession(); + + /// Whether the native SDK supports syncing the trace. + bool get supportsTraceSync; + + /// Sets the trace context on the native SDK scope. + FutureOr setTrace(SentryId traceId, SpanId spanId); } diff --git a/packages/flutter/lib/src/native/sentry_native_channel.dart b/packages/flutter/lib/src/native/sentry_native_channel.dart index 10726fdc3a..baed785529 100644 --- a/packages/flutter/lib/src/native/sentry_native_channel.dart +++ b/packages/flutter/lib/src/native/sentry_native_channel.dart @@ -422,4 +422,21 @@ class SentryNativeChannel FutureOr updateSession({int? errors, String? status}) { _logNotSupported('updating session'); } + + // Android handles supporting trace sync via JNI, not method channels. + @override + bool get supportsTraceSync => !options.platform.isAndroid; + + @override + FutureOr setTrace(SentryId traceId, SpanId spanId) { + if (options.platform.isAndroid) { + assert(false, + 'setTrace should not be used through method channels on Android.'); + return null; + } + return channel.invokeMethod('setTrace', { + 'traceId': traceId.toString(), + 'spanId': spanId.toString(), + }); + } } diff --git a/packages/flutter/lib/src/sentry_flutter.dart b/packages/flutter/lib/src/sentry_flutter.dart index 3ec4d43cd9..1c51b0666e 100644 --- a/packages/flutter/lib/src/sentry_flutter.dart +++ b/packages/flutter/lib/src/sentry_flutter.dart @@ -25,6 +25,7 @@ import 'integrations/native_app_start_handler.dart'; import 'integrations/replay_telemetry_integration.dart'; import 'integrations/screenshot_integration.dart'; import 'integrations/generic_app_start_integration.dart'; +import 'integrations/native_trace_sync_integration.dart'; import 'integrations/thread_info_integration.dart'; import 'integrations/web_session_integration.dart'; import 'native/factory.dart'; @@ -189,6 +190,9 @@ mixin SentryFlutter { // We also need to call this before the native sdk integrations so release is properly propagated. integrations.add(LoadReleaseIntegration()); integrations.add(createSdkIntegration(native)); + if (native.supportsTraceSync) { + integrations.add(NativeTraceSyncIntegration(native)); + } integrations.add(createLoadDebugImagesIntegration(native)); if (!platform.isWeb) { if (native.supportsLoadContexts) { diff --git a/packages/flutter/lib/src/sentry_flutter_options.dart b/packages/flutter/lib/src/sentry_flutter_options.dart index 0de7aebfe6..d88afa0209 100644 --- a/packages/flutter/lib/src/sentry_flutter_options.dart +++ b/packages/flutter/lib/src/sentry_flutter_options.dart @@ -284,6 +284,13 @@ class SentryFlutterOptions extends SentryOptions { /// you must use `SentryWidgetsFlutterBinding.ensureInitialized()` instead. bool enableFramesTracking = true; + /// Whether to synchronize the Dart trace to the native SDK. + /// + /// Allows native events to share the same trace as Dart events. + /// + /// Supported on Android and iOS/macOS. + bool enableNativeTraceSync = true; + /// Replay recording configuration. final replay = SentryReplayOptions(); diff --git a/packages/flutter/lib/src/web/sentry_web.dart b/packages/flutter/lib/src/web/sentry_web.dart index 05fe22e09b..b55a12c99b 100644 --- a/packages/flutter/lib/src/web/sentry_web.dart +++ b/packages/flutter/lib/src/web/sentry_web.dart @@ -257,6 +257,11 @@ class SentryWeb with SentryNativeSafeInvoker implements SentryNativeBinding { _logNotSupported('set user'); } + @override + FutureOr setTrace(SentryId traceId, SpanId spanId) { + _logNotSupported('setting trace'); + } + @override int? startProfiler(SentryId traceId) { _logNotSupported('start profiler'); @@ -275,6 +280,9 @@ class SentryWeb with SentryNativeSafeInvoker implements SentryNativeBinding { @override SentryId? get replayId => null; + @override + bool get supportsTraceSync => false; + @override SentryFlutterOptions get options => _options; } diff --git a/packages/flutter/test/integrations/native_trace_sync_integration_test.dart b/packages/flutter/test/integrations/native_trace_sync_integration_test.dart new file mode 100644 index 0000000000..d1f1c1d6c1 --- /dev/null +++ b/packages/flutter/test/integrations/native_trace_sync_integration_test.dart @@ -0,0 +1,101 @@ +// ignore_for_file: invalid_use_of_internal_member + +@TestOn('vm') +library; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_flutter/src/integrations/native_trace_sync_integration.dart'; +import 'package:sentry_flutter/src/native/sentry_native_binding.dart'; + +import '../mocks.dart'; + +void main() { + group(NativeTraceSyncIntegration, () { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + test('adds integration', () { + fixture.registerIntegration(); + + expect(fixture.options.sdk.integrations, + contains(NativeTraceSyncIntegration.integrationName)); + }); + + test('does not add integration if enableNativeTraceSync is false', () { + fixture.options.enableNativeTraceSync = false; + fixture.registerIntegration(); + + expect(fixture.options.sdk.integrations, + isNot(contains(NativeTraceSyncIntegration.integrationName))); + }); + + test('does not sync trace if enableNativeTraceSync is false', () { + fixture.options.enableNativeTraceSync = false; + fixture.registerIntegration(); + + fixture.hub.generateNewTrace(); + + expect(fixture.binding.setTraceCalls, isEmpty); + }); + + test('syncs initial propagation context on registration', () { + fixture.registerIntegration(); + + final call = fixture.binding.setTraceCalls.single; + expect(call.traceId, fixture.hub.scope.propagationContext.traceId); + }); + + test('syncs trace when OnTraceReset is dispatched', () { + fixture.registerIntegration(); + fixture.binding.setTraceCalls.clear(); + + fixture.hub.generateNewTrace(); + + // We cannot assert that the trace propagated to native here + // instead we just assert that the call was made with the correct trace ID. + final call = fixture.binding.setTraceCalls.single; + expect(call.traceId, fixture.hub.scope.propagationContext.traceId); + }); + + test('unregisters callback on close', () { + fixture.registerIntegration(); + fixture.binding.setTraceCalls.clear(); + + fixture.sut.close(); + fixture.hub.generateNewTrace(); + + expect(fixture.binding.setTraceCalls, isEmpty); + }); + }); +} + +class Fixture { + final options = defaultTestOptions(); + final binding = _FakeNativeBinding(); + late final hub = Hub(options); + late final sut = NativeTraceSyncIntegration(binding); + + void registerIntegration() { + sut.call(hub, options); + } +} + +class _SetTraceCall { + final SentryId traceId; + final SpanId spanId; + + _SetTraceCall(this.traceId, this.spanId); +} + +class _FakeNativeBinding extends Fake implements SentryNativeBinding { + final setTraceCalls = <_SetTraceCall>[]; + + @override + void setTrace(SentryId traceId, SpanId spanId) { + setTraceCalls.add(_SetTraceCall(traceId, spanId)); + } +} diff --git a/packages/flutter/test/mocks.dart b/packages/flutter/test/mocks.dart index 7c59da2b7f..5081e79508 100644 --- a/packages/flutter/test/mocks.dart +++ b/packages/flutter/test/mocks.dart @@ -184,6 +184,7 @@ class NativeChannelFixture { handler = MockCallbacks().methodCallHandler; when(handler('initNativeSdk', any)).thenAnswer((_) => Future.value()); when(handler('closeNativeSdk', any)).thenAnswer((_) => Future.value()); + when(handler('setTrace', any)).thenAnswer((_) => Future.value()); _messenger.setMockMethodCallHandler( channel, (call) => handler(call.method, call.arguments)); } diff --git a/packages/flutter/test/mocks.mocks.dart b/packages/flutter/test/mocks.mocks.dart index db45428c78..33c864a792 100644 --- a/packages/flutter/test/mocks.mocks.dart +++ b/packages/flutter/test/mocks.mocks.dart @@ -4,14 +4,14 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i12; -import 'dart:developer' as _i23; -import 'dart:typed_data' as _i19; +import 'dart:developer' as _i22; +import 'dart:typed_data' as _i18; import 'dart:ui' as _i6; import 'package:flutter/foundation.dart' as _i8; import 'package:flutter/gestures.dart' as _i7; import 'package:flutter/rendering.dart' as _i10; -import 'package:flutter/scheduler.dart' as _i22; +import 'package:flutter/scheduler.dart' as _i21; import 'package:flutter/services.dart' as _i4; import 'package:flutter/src/widgets/_window.dart' as _i11; import 'package:flutter/src/widgets/binding.dart' as _i5; @@ -21,19 +21,18 @@ import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i15; import 'package:sentry/src/profiling.dart' as _i16; import 'package:sentry/src/sentry_tracer.dart' as _i3; -import 'package:sentry/src/telemetry/metric/metric.dart' as _i17; import 'package:sentry_flutter/sentry_flutter.dart' as _i2; import 'package:sentry_flutter/src/frames_tracking/sentry_delayed_frames_tracker.dart' - as _i21; -import 'package:sentry_flutter/src/native/sentry_native_binding.dart' as _i18; + as _i20; +import 'package:sentry_flutter/src/native/sentry_native_binding.dart' as _i17; import 'package:sentry_flutter/src/navigation/time_to_display_tracker.dart' - as _i25; + as _i24; import 'package:sentry_flutter/src/navigation/time_to_full_display_tracker.dart' - as _i27; -import 'package:sentry_flutter/src/navigation/time_to_initial_display_tracker.dart' as _i26; -import 'package:sentry_flutter/src/replay/replay_config.dart' as _i20; -import 'package:sentry_flutter/src/web/sentry_js_binding.dart' as _i24; +import 'package:sentry_flutter/src/navigation/time_to_initial_display_tracker.dart' + as _i25; +import 'package:sentry_flutter/src/replay/replay_config.dart' as _i19; +import 'package:sentry_flutter/src/web/sentry_js_binding.dart' as _i23; import 'mocks.dart' as _i14; @@ -1767,7 +1766,7 @@ class MockSentryClient extends _i1.Mock implements _i2.SentryClient { @override _i12.Future captureMetric( - _i17.SentryMetric? metric, { + _i2.SentryMetric? metric, { _i2.Scope? scope, }) => (super.noSuchMethod( @@ -1880,7 +1879,7 @@ class MockMethodChannel extends _i1.Mock implements _i4.MethodChannel { /// /// See the documentation for Mockito's code generation for more information. class MockSentryNativeBinding extends _i1.Mock - implements _i18.SentryNativeBinding { + implements _i17.SentryNativeBinding { MockSentryNativeBinding() { _i1.throwOnMissingStub(this); } @@ -1903,6 +1902,12 @@ class MockSentryNativeBinding extends _i1.Mock returnValue: false, ) as bool); + @override + bool get supportsTraceSync => (super.noSuchMethod( + Invocation.getter(#supportsTraceSync), + returnValue: false, + ) as bool); + @override _i12.FutureOr init(_i2.Hub? hub) => (super.noSuchMethod(Invocation.method( @@ -1912,7 +1917,7 @@ class MockSentryNativeBinding extends _i1.Mock @override _i12.FutureOr captureEnvelope( - _i19.Uint8List? envelopeData, + _i18.Uint8List? envelopeData, bool? containsUnhandledException, ) => (super.noSuchMethod(Invocation.method( @@ -2035,7 +2040,7 @@ class MockSentryNativeBinding extends _i1.Mock )) as _i12.FutureOr?>); @override - _i12.FutureOr setReplayConfig(_i20.ReplayConfig? config) => + _i12.FutureOr setReplayConfig(_i19.ReplayConfig? config) => (super.noSuchMethod(Invocation.method( #setReplayConfig, [config], @@ -2063,25 +2068,38 @@ class MockSentryNativeBinding extends _i1.Mock [], {#ignoreDuration: ignoreDuration}, )) as _i12.FutureOr); + + @override + _i12.FutureOr setTrace( + _i2.SentryId? traceId, + _i2.SpanId? spanId, + ) => + (super.noSuchMethod(Invocation.method( + #setTrace, + [ + traceId, + spanId, + ], + )) as _i12.FutureOr); } /// A class which mocks [SentryDelayedFramesTracker]. /// /// See the documentation for Mockito's code generation for more information. class MockSentryDelayedFramesTracker extends _i1.Mock - implements _i21.SentryDelayedFramesTracker { + implements _i20.SentryDelayedFramesTracker { MockSentryDelayedFramesTracker() { _i1.throwOnMissingStub(this); } @override - List<_i21.SentryFrameTiming> get delayedFrames => (super.noSuchMethod( + List<_i20.SentryFrameTiming> get delayedFrames => (super.noSuchMethod( Invocation.getter(#delayedFrames), - returnValue: <_i21.SentryFrameTiming>[], - ) as List<_i21.SentryFrameTiming>); + returnValue: <_i20.SentryFrameTiming>[], + ) as List<_i20.SentryFrameTiming>); @override - List<_i21.SentryFrameTiming> getFramesIntersecting({ + List<_i20.SentryFrameTiming> getFramesIntersecting({ required DateTime? startTimestamp, required DateTime? endTimestamp, }) => @@ -2094,8 +2112,8 @@ class MockSentryDelayedFramesTracker extends _i1.Mock #endTimestamp: endTimestamp, }, ), - returnValue: <_i21.SentryFrameTiming>[], - ) as List<_i21.SentryFrameTiming>); + returnValue: <_i20.SentryFrameTiming>[], + ) as List<_i20.SentryFrameTiming>); @override void addDelayedFrame( @@ -2124,7 +2142,7 @@ class MockSentryDelayedFramesTracker extends _i1.Mock ); @override - _i21.SpanFrameMetrics? getFrameMetrics({ + _i20.SpanFrameMetrics? getFrameMetrics({ required DateTime? spanStartTimestamp, required DateTime? spanEndTimestamp, }) => @@ -2135,7 +2153,7 @@ class MockSentryDelayedFramesTracker extends _i1.Mock #spanStartTimestamp: spanStartTimestamp, #spanEndTimestamp: spanEndTimestamp, }, - )) as _i21.SpanFrameMetrics?); + )) as _i20.SpanFrameMetrics?); @override void clear() => super.noSuchMethod( @@ -2274,14 +2292,14 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i22.SchedulingStrategy get schedulingStrategy => (super.noSuchMethod( + _i21.SchedulingStrategy get schedulingStrategy => (super.noSuchMethod( Invocation.getter(#schedulingStrategy), returnValue: ({ required int priority, - required _i22.SchedulerBinding scheduler, + required _i21.SchedulerBinding scheduler, }) => false, - ) as _i22.SchedulingStrategy); + ) as _i21.SchedulingStrategy); @override int get transientCallbackCount => (super.noSuchMethod( @@ -2302,10 +2320,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - _i22.SchedulerPhase get schedulerPhase => (super.noSuchMethod( + _i21.SchedulerPhase get schedulerPhase => (super.noSuchMethod( Invocation.getter(#schedulerPhase), - returnValue: _i22.SchedulerPhase.idle, - ) as _i22.SchedulerPhase); + returnValue: _i21.SchedulerPhase.idle, + ) as _i21.SchedulerPhase); @override bool get framesEnabled => (super.noSuchMethod( @@ -2332,7 +2350,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as Duration); @override - set schedulingStrategy(_i22.SchedulingStrategy? value) => super.noSuchMethod( + set schedulingStrategy(_i21.SchedulingStrategy? value) => super.noSuchMethod( Invocation.setter( #schedulingStrategy, value, @@ -2929,10 +2947,10 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override _i12.Future scheduleTask( - _i22.TaskCallback? task, - _i22.Priority? priority, { + _i21.TaskCallback? task, + _i21.Priority? priority, { String? debugLabel, - _i23.Flow? flow, + _i22.Flow? flow, }) => (super.noSuchMethod( Invocation.method( @@ -2990,7 +3008,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override int scheduleFrameCallback( - _i22.FrameCallback? callback, { + _i21.FrameCallback? callback, { bool? rescheduling = false, bool? scheduleNewFrame = true, }) => @@ -3044,7 +3062,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock ) as bool); @override - void addPersistentFrameCallback(_i22.FrameCallback? callback) => + void addPersistentFrameCallback(_i21.FrameCallback? callback) => super.noSuchMethod( Invocation.method( #addPersistentFrameCallback, @@ -3055,7 +3073,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock @override void addPostFrameCallback( - _i22.FrameCallback? callback, { + _i21.FrameCallback? callback, { String? debugLabel = 'callback', }) => super.noSuchMethod( @@ -3131,12 +3149,12 @@ class MockWidgetsFlutterBinding extends _i1.Mock ); @override - _i22.PerformanceModeRequestHandle? requestPerformanceMode( + _i21.PerformanceModeRequestHandle? requestPerformanceMode( _i6.DartPerformanceMode? mode) => (super.noSuchMethod(Invocation.method( #requestPerformanceMode, [mode], - )) as _i22.PerformanceModeRequestHandle?); + )) as _i21.PerformanceModeRequestHandle?); @override void handleDrawFrame() => super.noSuchMethod( @@ -3725,7 +3743,7 @@ class MockWidgetsFlutterBinding extends _i1.Mock /// A class which mocks [SentryJsBinding]. /// /// See the documentation for Mockito's code generation for more information. -class MockSentryJsBinding extends _i1.Mock implements _i24.SentryJsBinding { +class MockSentryJsBinding extends _i1.Mock implements _i23.SentryJsBinding { MockSentryJsBinding() { _i1.throwOnMissingStub(this); } @@ -3797,7 +3815,7 @@ class MockSentryJsBinding extends _i1.Mock implements _i24.SentryJsBinding { /// /// See the documentation for Mockito's code generation for more information. class MockTimeToDisplayTracker extends _i1.Mock - implements _i25.TimeToDisplayTracker { + implements _i24.TimeToDisplayTracker { MockTimeToDisplayTracker() { _i1.throwOnMissingStub(this); } @@ -3884,7 +3902,7 @@ class MockTimeToDisplayTracker extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTimeToInitialDisplayTracker extends _i1.Mock - implements _i26.TimeToInitialDisplayTracker { + implements _i25.TimeToInitialDisplayTracker { MockTimeToInitialDisplayTracker() { _i1.throwOnMissingStub(this); } @@ -3920,7 +3938,7 @@ class MockTimeToInitialDisplayTracker extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockTimeToFullDisplayTracker extends _i1.Mock - implements _i27.TimeToFullDisplayTracker { + implements _i26.TimeToFullDisplayTracker { MockTimeToFullDisplayTracker() { _i1.throwOnMissingStub(this); } @@ -4160,7 +4178,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { )) as _i12.FutureOr); @override - _i12.Future captureMetric(_i17.SentryMetric? metric) => + _i12.Future captureMetric(_i2.SentryMetric? metric) => (super.noSuchMethod( Invocation.method( #captureMetric, From dfb673fc046146d920d5b0f1e74b29a5149fd616 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 17:30:12 +0100 Subject: [PATCH 48/62] chore(deps): update Native SDK to v0.12.6 (#3502) * chore: update packages/flutter/scripts/update-native.sh to 0.12.6 * Update gitignore --------- Co-authored-by: GitHub Co-authored-by: Giancarlo Buenaflor --- .gitignore | 1 + CHANGELOG.md | 3 +++ packages/flutter/sentry-native/CMakeCache.txt | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c757ee039a..42cbdaf05e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ build/ .cxx/ .vscode/ .fvm/ +.fvmrc .test_coverage.dart packages/**/coverage/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 4caf809621..09cd1803e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ - Bump JavaScript SDK from v10.6.0 to v10.38.0 ([#3474](https://github.com/getsentry/sentry-dart/pull/3474)) - [changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#10380) - [diff](https://github.com/getsentry/sentry-javascript/compare/10.6.0...10.38.0) +- Bump Native SDK from v0.12.5 to v0.12.6 ([#3502](https://github.com/getsentry/sentry-dart/pull/3502)) + - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0126) + - [diff](https://github.com/getsentry/sentry-native/compare/0.12.5...0.12.6) ## 9.12.0 diff --git a/packages/flutter/sentry-native/CMakeCache.txt b/packages/flutter/sentry-native/CMakeCache.txt index e6ee1ebd77..811fc9671f 100644 --- a/packages/flutter/sentry-native/CMakeCache.txt +++ b/packages/flutter/sentry-native/CMakeCache.txt @@ -2,4 +2,4 @@ # Basically, this is a properties file we use both in CMake and update-deps.yml to update dependencies. repo=https://github.com/getsentry/sentry-native -version=0.12.5 +version=0.12.6 From a920b0f9018dcb7a28d1969e64ad6bfedb6bafc6 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 12 Feb 2026 17:30:36 +0100 Subject: [PATCH 49/62] internal(flutter): Add SDK features metadata for SPM vs CocoaPods tracking (#3508) * feat(dart): Add `features` list to `SdkVersion` metadata Co-Authored-By: Claude Opus 4.6 * feat(flutter): Merge native SDK features into event metadata Co-Authored-By: Claude Opus 4.6 * feat(flutter): Report SPM vs CocoaPods build type as SDK feature on iOS Co-Authored-By: Claude Opus 4.6 * Review * Remove redundant comments --------- Co-authored-by: Claude Opus 4.6 --- CHANGELOG.md | 7 ++++ .../dart/lib/src/protocol/sdk_version.dart | 23 ++++++++++++- .../dart/test/protocol/sdk_version_test.dart | 20 ++++++++++++ .../flutter/ios/sentry_flutter/Package.swift | 3 ++ .../sentry_flutter/SentryFlutterPlugin.swift | 19 +++++++++++ .../load_contexts_integration.dart | 12 +++++++ packages/flutter/lib/src/sentry_flutter.dart | 1 + .../load_contexts_integration_test.dart | 32 +++++++++++++++++++ 8 files changed, 116 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09cd1803e1..1fcf3b704a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,13 @@ - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0126) - [diff](https://github.com/getsentry/sentry-native/compare/0.12.5...0.12.6) +
+Internal Changes + +- Add SDK features metadata for SPM vs CocoaPods tracking ([#3508](https://github.com/getsentry/sentry-dart/pull/3508)) + +
+ ## 9.12.0 ### Dependencies diff --git a/packages/dart/lib/src/protocol/sdk_version.dart b/packages/dart/lib/src/protocol/sdk_version.dart index b80483accd..5b059a0ea4 100644 --- a/packages/dart/lib/src/protocol/sdk_version.dart +++ b/packages/dart/lib/src/protocol/sdk_version.dart @@ -21,6 +21,9 @@ import 'access_aware_map.dart'; /// "integrations": [ /// "tracing" /// ], +/// "features": [ +/// "SwiftPackageManager" +/// ], /// "packages": [ /// { /// "name": "git:https://github.com/getsentry/sentry-cocoa.git", @@ -39,11 +42,13 @@ class SdkVersion { required this.name, required this.version, List? integrations, + List? features, List? packages, this.unknown, }) : // List.from prevents from having immutable lists _integrations = List.from(integrations ?? []), + _features = List.from(features ?? []), _packages = List.from(packages ?? []); /// The name of the SDK. @@ -57,6 +62,11 @@ class SdkVersion { /// An immutable list of integrations enabled in the SDK that created the [Event]. List get integrations => List.unmodifiable(_integrations); + List _features; + + /// An immutable list of features enabled in the SDK. + List get features => List.unmodifiable(_features); + List _packages; /// An immutable list of packages that compose this SDK. @@ -70,6 +80,7 @@ class SdkVersion { final json = AccessAwareMap(data); final packagesJson = json['packages'] as List?; final integrationsJson = json['integrations'] as List?; + final featuresJson = json['features'] as List?; return SdkVersion( name: json['name'], @@ -78,6 +89,7 @@ class SdkVersion { ?.map((e) => SentryPackage.fromJson(e as Map)) .toList(), integrations: integrationsJson?.map((e) => e as String).toList(), + features: featuresJson?.map((e) => e as String).toList(), unknown: json.notAccessed(), ); } @@ -91,6 +103,7 @@ class SdkVersion { if (packages.isNotEmpty) 'packages': packages.map((p) => p.toJson()).toList(growable: false), if (integrations.isNotEmpty) 'integrations': integrations, + if (features.isNotEmpty) 'features': features, }; } @@ -106,7 +119,6 @@ class SdkVersion { _packages.add(package); } - // Adds an integration if not already added void addIntegration(String integration) { if (_integrations.contains(integration)) { return; @@ -114,17 +126,26 @@ class SdkVersion { _integrations.add(integration); } + void addFeature(String feature) { + if (_features.contains(feature)) { + return; + } + _features.add(feature); + } + @Deprecated('Assign values directly to the instance.') SdkVersion copyWith({ String? name, String? version, List? integrations, + List? features, List? packages, }) => SdkVersion( name: name ?? this.name, version: version ?? this.version, integrations: integrations ?? _integrations, + features: features ?? _features, packages: packages ?? _packages, unknown: unknown, ); diff --git a/packages/dart/test/protocol/sdk_version_test.dart b/packages/dart/test/protocol/sdk_version_test.dart index 26ddddbb40..6be608f0f8 100644 --- a/packages/dart/test/protocol/sdk_version_test.dart +++ b/packages/dart/test/protocol/sdk_version_test.dart @@ -82,6 +82,24 @@ void main() { expect(1, sut.packages.length); }); }); + + group('addFeature', () { + final fixture = Fixture(); + + test('add feature if not already present', () { + final sut = fixture.getSut(); + sut.addFeature('newFeature'); + + expect(sut.features.last, 'newFeature'); + }); + + test('does not add feature if already present', () { + final sut = fixture.getSut(); + sut.addFeature('testFeature'); + + expect(sut.features.where((f) => f == 'testFeature').length, 1); + }); + }); } class Fixture { @@ -95,6 +113,7 @@ class Fixture { 'version': 'version', } ], + 'features': ['testFeature'], }; Fixture() { @@ -106,6 +125,7 @@ class Fixture { version: 'version', integrations: ['test'], packages: [SentryPackage('name', 'version')], + features: ['testFeature'], unknown: testUnknown, ); } diff --git a/packages/flutter/ios/sentry_flutter/Package.swift b/packages/flutter/ios/sentry_flutter/Package.swift index 6f9bf24d3c..89b109d62b 100644 --- a/packages/flutter/ios/sentry_flutter/Package.swift +++ b/packages/flutter/ios/sentry_flutter/Package.swift @@ -21,6 +21,9 @@ let package = Package( dependencies: [ "sentry_flutter_objc", .product(name: "Sentry", package: "sentry-cocoa") + ], + swiftSettings: [ + .define("SENTRY_FLUTTER_SPM") ] ), // SPM does not support mixed-language targets, so we need to move the ObjC files into a separate one 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 a894c8daf5..e30d522160 100644 --- a/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift +++ b/packages/flutter/ios/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift @@ -219,6 +219,12 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { infos["integrations"] = integrations.filter { $0 != "SentrySessionReplayIntegration" } } + #if SENTRY_FLUTTER_SPM + infos["features"] = ["SwiftPackageManager"] + #else + infos["features"] = ["CocoaPods"] + #endif + let deviceStr = "device" let appStr = "app" if let extraContext = PrivateSentrySDKOnly.getExtraContext() as? [String: Any] { @@ -247,8 +253,13 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { // Not reading the name from PrivateSentrySDKOnly.getSdkName because // this is added as a package and packages should follow the sentry-release-registry format + #if SENTRY_FLUTTER_SPM + infos["package"] = ["version": PrivateSentrySDKOnly.getSdkVersionString(), + "sdk_name": "spm:sentry-cocoa"] + #else infos["package"] = ["version": PrivateSentrySDKOnly.getSdkVersionString(), "sdk_name": "cocoapods:sentry-cocoa"] + #endif result(infos) } @@ -282,6 +293,7 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { result(debugImages.map { $0.serialize() }) } + // swiftlint:disable:next cyclomatic_complexity private func initNativeSdk(_ call: FlutterMethodCall, result: @escaping FlutterResult) { guard let arguments = call.arguments as? [String: Any], !arguments.isEmpty else { print("Arguments is null or empty") @@ -325,6 +337,13 @@ public class SentryFlutterPlugin: NSObject, FlutterPlugin { sdk["integrations"] = integrations } } + if let features = flutterSdk!["features"] as? [String] { + if let sdkFeatures = sdk["features"] as? [String] { + sdk["features"] = sdkFeatures + features + } else { + sdk["features"] = features + } + } event.sdk = sdk } } diff --git a/packages/flutter/lib/src/integrations/load_contexts_integration.dart b/packages/flutter/lib/src/integrations/load_contexts_integration.dart index b46a7a7494..b50669b686 100644 --- a/packages/flutter/lib/src/integrations/load_contexts_integration.dart +++ b/packages/flutter/lib/src/integrations/load_contexts_integration.dart @@ -260,6 +260,18 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { event.sdk = sdk; } + final featuresList = infos['features'] as List?; + if (featuresList != null && featuresList.isNotEmpty) { + final features = List.from(featuresList); + final sdk = event.sdk ?? _options.sdk; + + for (final feature in features) { + sdk.addFeature(feature); + } + + event.sdk = sdk; + } + final packageMap = infos['package'] as Map?; if (packageMap != null && packageMap.isNotEmpty) { final package = Map.from(packageMap); diff --git a/packages/flutter/lib/src/sentry_flutter.dart b/packages/flutter/lib/src/sentry_flutter.dart index 1c51b0666e..86462f87b4 100644 --- a/packages/flutter/lib/src/sentry_flutter.dart +++ b/packages/flutter/lib/src/sentry_flutter.dart @@ -264,6 +264,7 @@ mixin SentryFlutter { version: sdkVersion, integrations: options.sdk.integrations, packages: options.sdk.packages, + features: options.sdk.features, ); sdk.addPackage('pub:sentry_flutter', sdkVersion); options.sdk = sdk; diff --git a/packages/flutter/test/integrations/load_contexts_integration_test.dart b/packages/flutter/test/integrations/load_contexts_integration_test.dart index f74f261bad..3ad809c363 100644 --- a/packages/flutter/test/integrations/load_contexts_integration_test.dart +++ b/packages/flutter/test/integrations/load_contexts_integration_test.dart @@ -14,6 +14,7 @@ import 'fixture.dart'; void main() { final defaultContexts = { 'integrations': ['NativeIntegration'], + 'features': ['SwiftPackageManager'], 'package': {'sdk_name': 'native-package', 'version': '1.0'}, 'contexts': { 'device': { @@ -291,6 +292,37 @@ void main() { ); }); + group('features', () { + test('merges features from native into sdk', () async { + mockLoadContexts(); + await fixture.registerIntegration(); + + final e = getEvent(); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect(event?.sdk?.features.contains('SwiftPackageManager'), true); + }); + + test('does not duplicate feature if already present', () async { + mockLoadContexts({ + 'features': ['EventFeature'] + }); + await fixture.registerIntegration(); + + final sdk = getSdkVersion(); + sdk.addFeature('EventFeature'); + final e = getEvent(sdk: sdk); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); + + expect( + event?.sdk?.features.where((f) => f == 'EventFeature').length, + 1, + ); + }); + }); + group('breadcrumbs', () { test('takes breadcrumbs from native if scope sync is enabled', () async { await fixture.registerIntegration(); From 98b3399a41789c8a273f679daf5ad499bb4bd88a Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 12 Feb 2026 16:31:35 +0000 Subject: [PATCH 50/62] release: 9.13.0 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fcf3b704a..a98c697c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.13.0 ### Features diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index 77c2310a62..a07d129d53 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.13.0 | 8.32.0 | 8.56.2 | 10.38.0 | 0.12.6 | | 9.12.0 | 8.31.0 | 8.56.2 | 10.6.0 | 0.12.5 | | 9.11.0 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | | 9.11.0-beta.2 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index 2cfbd14625..41bf5a924c 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index 06d96fc61d..a29d4df18f 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.12.0 +version: 9.13.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index ae74e815ec..b4e3f3af5b 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index 522db4cf23..db7eeb17d2 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.12.0 + sentry: 9.13.0 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index a49d5d08e9..005f46fc3a 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 11b6cf26d1..5255cd7222 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.12.0 + sentry: 9.13.0 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 8a4b1e0ab0..6b074bf411 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index 9ee37ba039..a4f5a845cd 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.12.0 + sentry: 9.13.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index 21a24123e3..1867defc2e 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.12.0 + sentry: 9.13.0 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index 48eb0e4f00..e68d072b0a 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.12.0 +version: 9.13.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 54b8ba31b9..7229002934 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 8ea4130542..e88ec96eac 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.12.0 +version: 9.13.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.12.0 + sentry: 9.13.0 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index fdb6bab603..012013cb34 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index a4e27b790a..265f4aa5af 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.12.0 + sentry: 9.13.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index fb5bd58f3c..ed8f085fd8 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index 7f6b8e933d..b283356611 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.12.0 + sentry: 9.13.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index c1b66a78ce..d37b48a2bd 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.12.0 + sentry: 9.13.0 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index bce6385477..bddcb3a066 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index ca3b63b822..ff8f2a106b 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.12.0 + sentry: 9.13.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index e78344c143..5df8459473 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.12.0'; +const String sdkVersion = '9.13.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index f0c64353f9..43471cf92b 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.12.0 + sentry: 9.13.0 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index cdef236c7d..adc308984f 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.12.0 +version: 9.13.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: http: ^1.3.0 meta: ^1.3.0 - sentry: 9.12.0 + sentry: 9.13.0 dev_dependencies: supabase: ^2.6.0 From 838a4f63d430b77722f8d0ef43a1a4854b587224 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 16 Feb 2026 12:24:47 +0000 Subject: [PATCH 51/62] ci(release): Switch from action-prepare-release to Craft (#3440) * ci(release): Switch from action-prepare-release to Craft This PR migrates from the deprecated action-prepare-release to the new Craft GitHub Actions (reusable workflow or composite action). Changes: - Migrate .github/workflows/release.yml to Craft reusable workflow * ci(release): Restore GitHub App token authentication The previous migration incorrectly removed the GitHub App token authentication step. This commit restores it by switching to the composite action pattern which preserves the auth flow. * fix: Pin actions to SHA and add permissions blocks * fix: Use correct action version SHAs (restore original versions) * fix: Use correct action version SHAs (restore original versions) * fix: Clean up action version comments * Update Craft SHA to 1c58bfd57bfd6a967b6f3fc92bead2c42ee698ce * Add explicit permissions block to analyze.yml * Add explicit permissions block to dart.yml * Add explicit permissions block to dio.yml * Add explicit permissions block to drift.yml * Add explicit permissions block to e2e_dart.yml * Add explicit permissions block to file.yml * Add explicit permissions block to firebase_remote_config.yml * Add explicit permissions block to flutter.yml * Add explicit permissions block to flutter_test.yml * Add explicit permissions block to format-and-fix.yml * Add explicit permissions block to hive.yml * Add explicit permissions block to isar.yml * Add explicit permissions block to link.yml * Add explicit permissions block to logging.yml * Add explicit permissions block to metrics.yml * Add explicit permissions block to min_version_test.yml * Add explicit permissions block to sqflite.yml * Add explicit permissions block to supabase.yml * Add explicit permissions block to testflight.yml * Add explicit permissions block to web-example-ghpages.yml * Revert permissions changes to analyze.yml * Revert permissions changes to dart.yml * Revert permissions changes to dio.yml * Revert permissions changes to drift.yml * Revert permissions changes to e2e_dart.yml * Revert permissions changes to file.yml * Revert permissions changes to firebase_remote_config.yml * Revert permissions changes to flutter.yml * Revert permissions changes to flutter_test.yml * Revert permissions changes to format-and-fix.yml * Revert permissions changes to hive.yml * Revert permissions changes to isar.yml * Revert permissions changes to link.yml * Revert permissions changes to logging.yml * Revert permissions changes to metrics.yml * Revert permissions changes to min_version_test.yml * Revert permissions changes to sqflite.yml * Revert permissions changes to supabase.yml * Revert permissions changes to testflight.yml * Revert permissions changes to web-example-ghpages.yml * fix: revert extraneous changes to non-release workflow files * fix: clean up release.yml formatting and version comments * build(craft): Update Craft action to c6e2f04 * chore: add unlabeled trigger to changelog-preview --- .github/workflows/changelog-preview.yml | 18 ++++++++++++++++++ .github/workflows/release.yml | 10 +++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/changelog-preview.yml diff --git a/.github/workflows/changelog-preview.yml b/.github/workflows/changelog-preview.yml new file mode 100644 index 0000000000..30c6083c6b --- /dev/null +++ b/.github/workflows/changelog-preview.yml @@ -0,0 +1,18 @@ +name: Changelog Preview +on: + pull_request: + types: + - opened + - synchronize + - reopened + - edited + - labeled + - unlabeled +permissions: + contents: write + pull-requests: write + +jobs: + changelog-preview: + uses: getsentry/craft/.github/workflows/changelog-preview.yml@v2 + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 258b43726e..a8baa948cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,8 +3,8 @@ on: workflow_dispatch: inputs: version: - description: Version to release - required: true + description: Version to release (or "auto") + required: false force: description: Force a release even when there are release-blockers (optional) required: false @@ -12,6 +12,10 @@ on: description: Target branch to merge into. Uses the default branch as a fallback (optional) required: false +permissions: + contents: write + pull-requests: write + jobs: release: runs-on: ubuntu-latest @@ -29,7 +33,7 @@ jobs: token: ${{ steps.token.outputs.token }} fetch-depth: 0 - name: Prepare release - uses: getsentry/action-prepare-release@c8e1c2009ab08259029170132c384f03c1064c0e + uses: getsentry/craft@c6e2f04939b6ee67030588afbb5af76b127d8203 # v2 env: GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: From 66e2de308a1fbb4806e972f30785c37f25a8d258 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:49:42 +0100 Subject: [PATCH 52/62] build(deps): bump faraday from 1.10.4 to 1.10.5 in /metrics (#3511) Bumps [faraday](https://github.com/lostisland/faraday) from 1.10.4 to 1.10.5. - [Release notes](https://github.com/lostisland/faraday/releases) - [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md) - [Commits](https://github.com/lostisland/faraday/compare/v1.10.4...v1.10.5) --- updated-dependencies: - dependency-name: faraday dependency-version: 1.10.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- metrics/Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metrics/Gemfile.lock b/metrics/Gemfile.lock index aff4675061..0df27322ca 100644 --- a/metrics/Gemfile.lock +++ b/metrics/Gemfile.lock @@ -46,7 +46,7 @@ GEM dotenv (2.8.1) emoji_regex (3.2.3) excon (0.112.0) - faraday (1.10.4) + faraday (1.10.5) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -65,7 +65,7 @@ GEM faraday-em_synchrony (1.0.1) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.1.1) + faraday-multipart (1.2.0) multipart-post (~> 2.0) faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) From ccb4ef6a89805062bfc02083960ddce3bec18345 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:50:03 +0100 Subject: [PATCH 53/62] chore: update packages/flutter/scripts/update-native.sh to 0.12.7 (#3514) Co-authored-by: GitHub --- CHANGELOG.md | 8 ++++++++ packages/flutter/sentry-native/CMakeCache.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a98c697c51..b7e379496f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Dependencies + +- Bump Native SDK from v0.12.6 to v0.12.7 ([#3514](https://github.com/getsentry/sentry-dart/pull/3514)) + - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0127) + - [diff](https://github.com/getsentry/sentry-native/compare/0.12.6...0.12.7) + ## 9.13.0 ### Features diff --git a/packages/flutter/sentry-native/CMakeCache.txt b/packages/flutter/sentry-native/CMakeCache.txt index 811fc9671f..efb844ac39 100644 --- a/packages/flutter/sentry-native/CMakeCache.txt +++ b/packages/flutter/sentry-native/CMakeCache.txt @@ -2,4 +2,4 @@ # Basically, this is a properties file we use both in CMake and update-deps.yml to update dependencies. repo=https://github.com/getsentry/sentry-native -version=0.12.6 +version=0.12.7 From 17777276b2d1dfdcca6fc09ebdb3a95987266f25 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:50:20 +0100 Subject: [PATCH 54/62] chore: update metrics/flutter.properties to 3.41.1 (#3486) Co-authored-by: GitHub --- metrics/flutter.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/flutter.properties b/metrics/flutter.properties index 39f226238d..2ff196df6d 100644 --- a/metrics/flutter.properties +++ b/metrics/flutter.properties @@ -1,2 +1,2 @@ -version = 3.38.7 +version = 3.41.1 repo = https://github.com/flutter/flutter From b469e31fa56adc4f9e702e89fbeaeff503adaae6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:50:45 +0100 Subject: [PATCH 55/62] build(deps): bump getsentry/craft from 2.19.0 to 2.21.4 (#3518) Bumps [getsentry/craft](https://github.com/getsentry/craft) from 2.19.0 to 2.21.4. - [Release notes](https://github.com/getsentry/craft/releases) - [Changelog](https://github.com/getsentry/craft/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/craft/compare/c6e2f04939b6ee67030588afbb5af76b127d8203...906009a1b771956757e521555b561379307eb667) --- updated-dependencies: - dependency-name: getsentry/craft dependency-version: 2.21.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8baa948cf..4661055508 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: token: ${{ steps.token.outputs.token }} fetch-depth: 0 - name: Prepare release - uses: getsentry/craft@c6e2f04939b6ee67030588afbb5af76b127d8203 # v2 + uses: getsentry/craft@906009a1b771956757e521555b561379307eb667 # v2 env: GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: From 50d0559e6044560702c6457ae63ed9d8c25c1c14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:51:04 +0100 Subject: [PATCH 56/62] build(deps): bump ruby/setup-ruby from 1.286.0 to 1.288.0 (#3519) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.286.0 to 1.288.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/90be1154f987f4dc0fe0dd0feedac9e473aa4ba8...09a7688d3b55cf0e976497ff046b70949eeaccfd) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.288.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/min_version_test.yml | 2 +- .github/workflows/testflight.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/min_version_test.yml b/.github/workflows/min_version_test.yml index 613538f0a7..847d230ea9 100644 --- a/.github/workflows/min_version_test.yml +++ b/.github/workflows/min_version_test.yml @@ -51,7 +51,7 @@ jobs: with: flutter-version: '3.24.0' - - uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # pin@v1.286.0 + - uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # pin@v1.288.0 with: ruby-version: '3.1.2' # https://github.com/flutter/flutter/issues/109385#issuecomment-1212614125 diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 91b6d53530..2a1db45d62 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v6 - uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0 - run: xcodes select 26.2 - - uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # pin@v1.286.0 + - uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # pin@v1.288.0 with: ruby-version: '2.7.5' bundler-cache: true From 3135a810f49c0ccf72f12a9cd795d0cd44ee49f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:26:24 +0100 Subject: [PATCH 57/62] chore: update packages/flutter/scripts/update-native.sh to 0.12.8 (#3520) Co-authored-by: GitHub --- CHANGELOG.md | 6 +++--- packages/flutter/sentry-native/CMakeCache.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7e379496f..1c33405ec9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ ### Dependencies -- Bump Native SDK from v0.12.6 to v0.12.7 ([#3514](https://github.com/getsentry/sentry-dart/pull/3514)) - - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0127) - - [diff](https://github.com/getsentry/sentry-native/compare/0.12.6...0.12.7) +- Bump Native SDK from v0.12.6 to v0.12.8 ([#3514](https://github.com/getsentry/sentry-dart/pull/3514), [#3520](https://github.com/getsentry/sentry-dart/pull/3520)) + - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0128) + - [diff](https://github.com/getsentry/sentry-native/compare/0.12.6...0.12.8) ## 9.13.0 diff --git a/packages/flutter/sentry-native/CMakeCache.txt b/packages/flutter/sentry-native/CMakeCache.txt index efb844ac39..4f54a153da 100644 --- a/packages/flutter/sentry-native/CMakeCache.txt +++ b/packages/flutter/sentry-native/CMakeCache.txt @@ -2,4 +2,4 @@ # Basically, this is a properties file we use both in CMake and update-deps.yml to update dependencies. repo=https://github.com/getsentry/sentry-native -version=0.12.7 +version=0.12.8 From 4cec1336cd31f1ef0e92775fc454bf00ba532a5e Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 18 Feb 2026 15:33:07 +0100 Subject: [PATCH 58/62] fix(dart): Dont guard user behind `sendDefaultPii` (#3524) * Dont guard user attributes with sendDEfaultPii * Update sample * Update CHANGELOG * Update comments --- CHANGELOG.md | 4 +++ packages/dart/lib/src/constants.dart | 15 ++++++---- .../lib/src/telemetry/default_attributes.dart | 30 +++++++++---------- .../log/log_capture_pipeline_test.dart | 16 ---------- .../metric/metric_capture_pipeline_test.dart | 16 ---------- packages/flutter/example/lib/main.dart | 9 ++++++ 6 files changed, 37 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c33405ec9..2fd8cb5d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- Dont guard user attributes behind `sendDefaultPii` for logs and metrics ([#3524](https://github.com/getsentry/sentry-dart/pull/3524)) + ### Dependencies - Bump Native SDK from v0.12.6 to v0.12.8 ([#3514](https://github.com/getsentry/sentry-dart/pull/3514), [#3520](https://github.com/getsentry/sentry-dart/pull/3520)) diff --git a/packages/dart/lib/src/constants.dart b/packages/dart/lib/src/constants.dart index 94759424df..cfc2f92e2c 100644 --- a/packages/dart/lib/src/constants.dart +++ b/packages/dart/lib/src/constants.dart @@ -89,16 +89,19 @@ abstract class SemanticAttributesConstants { static const sentryInternalReplayIsBuffering = 'sentry._internal.replay_is_buffering'; - /// The user ID (gated by `sendDefaultPii`). + /// The user ID. + /// Users are always manually set and never automatically inferred, + /// therefore this is not gated by `sendDefaultPii`. static const userId = 'user.id'; - /// The user email (gated by `sendDefaultPii`). + /// The user email. + /// Users are always manually set and never automatically inferred, + /// therefore this is not gated by `sendDefaultPii`. static const userEmail = 'user.email'; - /// The user IP address (gated by `sendDefaultPii`). - static const userIpAddress = 'user.ip_address'; - - /// The user username (gated by `sendDefaultPii`). + /// The user username. + /// Users are always manually set and never automatically inferred, + /// therefore this is not gated by `sendDefaultPii`. static const userName = 'user.name'; /// The operating system name. diff --git a/packages/dart/lib/src/telemetry/default_attributes.dart b/packages/dart/lib/src/telemetry/default_attributes.dart index 93facb066a..d71ca991bb 100644 --- a/packages/dart/lib/src/telemetry/default_attributes.dart +++ b/packages/dart/lib/src/telemetry/default_attributes.dart @@ -23,21 +23,21 @@ Map defaultAttributes(SentryOptions options, SentryAttribute.string(options.release!); } - if (options.sendDefaultPii) { - final user = scope?.user; - if (user != null) { - if (user.id != null) { - attributes[SemanticAttributesConstants.userId] = - SentryAttribute.string(user.id!); - } - if (user.name != null) { - attributes[SemanticAttributesConstants.userName] = - SentryAttribute.string(user.name!); - } - if (user.email != null) { - attributes[SemanticAttributesConstants.userEmail] = - SentryAttribute.string(user.email!); - } + // Users are always manually set and never automatically inferred, + // therefore this is not gated by `sendDefaultPii`. + final user = scope?.user; + if (user != null) { + if (user.id != null) { + attributes[SemanticAttributesConstants.userId] = + SentryAttribute.string(user.id!); + } + if (user.name != null) { + attributes[SemanticAttributesConstants.userName] = + SentryAttribute.string(user.name!); + } + if (user.email != null) { + attributes[SemanticAttributesConstants.userEmail] = + SentryAttribute.string(user.email!); } } diff --git a/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart b/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart index 5c6179f99e..ffbe119712 100644 --- a/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart +++ b/packages/dart/test/telemetry/log/log_capture_pipeline_test.dart @@ -129,21 +129,6 @@ void main() { expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, 'callback-env'); }); - - test('does not add user attributes when sendDefaultPii is false', - () async { - fixture.options.sendDefaultPii = false; - await fixture.scope.setUser(SentryUser(id: 'user-id')); - - final log = givenLog(); - - await fixture.pipeline.captureLog(log, scope: fixture.scope); - - expect( - log.attributes.containsKey(SemanticAttributesConstants.userId), - isFalse, - ); - }); }); group('when logs are disabled', () { @@ -239,7 +224,6 @@ class Fixture { final options = defaultTestOptions() ..environment = 'test-env' ..release = 'test-release' - ..sendDefaultPii = true ..enableLogs = true; final processor = MockTelemetryProcessor(); diff --git a/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart b/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart index e60f63d0e6..4d235796a3 100644 --- a/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart +++ b/packages/dart/test/telemetry/metric/metric_capture_pipeline_test.dart @@ -118,21 +118,6 @@ void main() { expect(attributes[SemanticAttributesConstants.sentryEnvironment]?.value, 'callback-env'); }); - - test('does not add user attributes when sendDefaultPii is false', - () async { - fixture.options.sendDefaultPii = false; - await fixture.scope.setUser(SentryUser(id: 'user-id')); - - final metric = fixture.createMetric(); - - await fixture.pipeline.captureMetric(metric, scope: fixture.scope); - - expect( - metric.attributes.containsKey(SemanticAttributesConstants.userId), - isFalse, - ); - }); }); group('when metrics are disabled', () { @@ -196,7 +181,6 @@ class Fixture { final options = defaultTestOptions() ..environment = 'test-env' ..release = 'test-release' - ..sendDefaultPii = true ..enableMetrics = true; final processor = MockTelemetryProcessor(); diff --git a/packages/flutter/example/lib/main.dart b/packages/flutter/example/lib/main.dart index 7f65a7f9c2..cb0c89ad91 100644 --- a/packages/flutter/example/lib/main.dart +++ b/packages/flutter/example/lib/main.dart @@ -114,6 +114,15 @@ Future setupSentry( // Init your App. appRunner: appRunner, ); + + Sentry.configureScope((scope) { + final user = SentryUser( + id: SentryId.newId().toString(), + name: 'J. Smith', + email: 'j.smith@example.com', + ); + scope.setUser(user); + }); } class MyApp extends StatefulWidget { From c6897c142a01512cb80f6638492603fe2d1d1e9e Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Thu, 19 Feb 2026 13:32:14 +0100 Subject: [PATCH 59/62] Add enableTombstone option for native crash reporting on Android (#3526) * feat(flutter): Add enableTombstone option for improved native crash reporting Add `enableTombstone` option to SentryFlutterOptions that enables tombstone-based native crash reporting on Android 12+ (API level 30+). When enabled, uses Android's `ApplicationExitInfo.REASON_CRASH_NATIVE` to capture native crashes with more detailed thread information. The option is disabled by default. Slack thread: https://sentry.slack.com/archives/CP4UUUF1S/p1771404252312029?thread_ts=1769055443.846779&cid=CP4UUUF1S https://claude.ai/code/session_016kkosYW3XG2rhHafEfspqA * Apply suggestion from @romtsn * Add integration test * Enable tombstone option in integration test --------- Co-authored-by: Claude Co-authored-by: Giancarlo Buenaflor Co-authored-by: Giancarlo Buenaflor --- CHANGELOG.md | 6 ++++++ .../flutter/example/integration_test/integration_test.dart | 4 ++++ .../lib/src/native/java/sentry_native_java_init.dart | 1 + packages/flutter/lib/src/sentry_flutter_options.dart | 6 ++++++ packages/flutter/test/sentry_flutter_options_test.dart | 7 +++++++ 5 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd8cb5d18..d346676227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +### Features + +- Add `enableTombstone` option for improved native crash reporting on Android 12+ ([#3526](https://github.com/getsentry/sentry-dart/pull/3526)) + - When enabled, uses Android's `ApplicationExitInfo.REASON_CRASH_NATIVE` to capture native crashes with more detailed thread information + - Disabled by default + ### Fixes - Dont guard user attributes behind `sendDefaultPii` for logs and metrics ([#3524](https://github.com/getsentry/sentry-dart/pull/3524)) diff --git a/packages/flutter/example/integration_test/integration_test.dart b/packages/flutter/example/integration_test/integration_test.dart index 787f47a80a..c90edc5f0a 100644 --- a/packages/flutter/example/integration_test/integration_test.dart +++ b/packages/flutter/example/integration_test/integration_test.dart @@ -217,6 +217,7 @@ void main() { options.anrTimeoutInterval = const Duration(seconds: 2); options.connectionTimeout = const Duration(milliseconds: 1234); options.readTimeout = const Duration(milliseconds: 2345); + options.enableTombstone = true; }); }); @@ -280,12 +281,15 @@ void main() { expect(findMatchingPackage, isNotNull); } expect(androidOptions.isEnableAutoTraceIdGeneration(), isFalse); + expect(androidOptions.isTombstoneEnabled(), isTrue); + final androidProxy = androidOptions.getProxy(); expect(androidProxy, isNotNull); expect(androidProxy!.getHost()?.toDartString(), 'proxy.local'); expect(androidProxy.getPort()?.toDartString(), '8084'); expect(androidProxy.getUser()?.toDartString(), 'u'); expect(androidProxy.getPass()?.toDartString(), 'p'); + final r = androidOptions.getSessionReplay(); expect(r.getQuality(), jni.SentryReplayOptions$SentryReplayQuality.HIGH); expect(r.getSessionSampleRate(), isNotNull); diff --git a/packages/flutter/lib/src/native/java/sentry_native_java_init.dart b/packages/flutter/lib/src/native/java/sentry_native_java_init.dart index 86004d5bc3..bb709dccf9 100644 --- a/packages/flutter/lib/src/native/java/sentry_native_java_init.dart +++ b/packages/flutter/lib/src/native/java/sentry_native_java_init.dart @@ -215,6 +215,7 @@ void configureAndroidOptions({ androidOptions .setAnrTimeoutIntervalMillis(options.anrTimeoutInterval.inMilliseconds); androidOptions.setAnrEnabled(options.anrEnabled); + androidOptions.setTombstoneEnabled(options.enableTombstone); androidOptions.setAttachThreads(options.attachThreads); androidOptions.setAttachStacktrace(options.attachStacktrace); diff --git a/packages/flutter/lib/src/sentry_flutter_options.dart b/packages/flutter/lib/src/sentry_flutter_options.dart index d88afa0209..b66d516b0a 100644 --- a/packages/flutter/lib/src/sentry_flutter_options.dart +++ b/packages/flutter/lib/src/sentry_flutter_options.dart @@ -68,6 +68,12 @@ class SentryFlutterOptions extends SentryOptions { /// Available only for Android. Enabled by default. bool anrEnabled = true; + /// Enable or disable Tombstone reporting for improved native crash reporting. + /// When enabled, uses Android's `ApplicationExitInfo.REASON_CRASH_NATIVE` to + /// capture native crashes with more detailed thread information. + /// Available only for Android 12+ (API level 30+). Disabled by default. + bool enableTombstone = false; + Duration _anrTimeoutInterval = Duration(milliseconds: 5000); /// ANR Timeout internal. Default is 5000 milliseconds or 5 seconds. diff --git a/packages/flutter/test/sentry_flutter_options_test.dart b/packages/flutter/test/sentry_flutter_options_test.dart index 81f723a061..a5b62284ab 100644 --- a/packages/flutter/test/sentry_flutter_options_test.dart +++ b/packages/flutter/test/sentry_flutter_options_test.dart @@ -51,5 +51,12 @@ void main() { expect(options.enableMemoryPressureBreadcrumbs, isTrue); expect(options.enableAutoNativeBreadcrumbs, isFalse); }); + + testWidgets('enableTombstone defaults to false', + (WidgetTester tester) async { + final options = defaultTestOptions(); + + expect(options.enableTombstone, isFalse); + }); }); } From d052aef70c108ed1c7d6c157f013a036a4937b70 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:35:28 +0100 Subject: [PATCH 60/62] chore(deps): update Android SDK to v8.33.0 (#3529) * chore: update packages/flutter/scripts/update-android.sh to 8.33.0 * Update jni call when creating bitmap --------- Co-authored-by: GitHub Co-authored-by: Giancarlo Buenaflor --- CHANGELOG.md | 3 + packages/flutter/android/build.gradle | 4 +- .../native/java/android_replay_recorder.dart | 2 +- .../flutter/lib/src/native/java/binding.dart | 9053 +++++++++-------- 4 files changed, 4609 insertions(+), 4453 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d346676227..80dbf760cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ - Bump Native SDK from v0.12.6 to v0.12.8 ([#3514](https://github.com/getsentry/sentry-dart/pull/3514), [#3520](https://github.com/getsentry/sentry-dart/pull/3520)) - [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#0128) - [diff](https://github.com/getsentry/sentry-native/compare/0.12.6...0.12.8) +- Bump Android SDK from v8.32.0 to v8.33.0 ([#3529](https://github.com/getsentry/sentry-dart/pull/3529)) + - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8330) + - [diff](https://github.com/getsentry/sentry-java/compare/8.32.0...8.33.0) ## 9.13.0 diff --git a/packages/flutter/android/build.gradle b/packages/flutter/android/build.gradle index 3d68acbc1a..df383b8f3a 100644 --- a/packages/flutter/android/build.gradle +++ b/packages/flutter/android/build.gradle @@ -62,8 +62,8 @@ android { } dependencies { - api 'io.sentry:sentry-android:8.32.0' - debugImplementation 'io.sentry:sentry-spotlight:8.32.0' + api 'io.sentry:sentry-android:8.33.0' + debugImplementation 'io.sentry:sentry-spotlight:8.33.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" // Required -- JUnit 4 framework diff --git a/packages/flutter/lib/src/native/java/android_replay_recorder.dart b/packages/flutter/lib/src/native/java/android_replay_recorder.dart index 38b7006ea7..c80f1dd7e1 100644 --- a/packages/flutter/lib/src/native/java/android_replay_recorder.dart +++ b/packages/flutter/lib/src/native/java/android_replay_recorder.dart @@ -131,7 +131,7 @@ class _AndroidReplayHandler extends WorkerHandler { // https://developer.android.com/reference/android/graphics/Bitmap#createBitmap(int,%20int,%20android.graphics.Bitmap.Config) // Note: while the generated API is nullable, the docs say the returned value cannot be null.. - _bitmap ??= native.Bitmap.createBitmap$3( + _bitmap ??= native.Bitmap.createBitmap$10( item.width, item.height, native.Bitmap$Config.ARGB_8888); jBuffer = JByteBuffer.fromList(item.data); diff --git a/packages/flutter/lib/src/native/java/binding.dart b/packages/flutter/lib/src/native/java/binding.dart index 249a58c6ac..5c4753254f 100644 --- a/packages/flutter/lib/src/native/java/binding.dart +++ b/packages/flutter/lib/src/native/java/binding.dart @@ -10231,6 +10231,28 @@ class SentryOptions$DistributionOptions extends jni$_.JObject { set buildConfiguration(jni$_.JString? value) => _id_buildConfiguration.set( this, const jni$_.JStringNullableType(), value); + static final _id_installGroupsOverride = _class.instanceFieldId( + r'installGroupsOverride', + r'Ljava/util/List;', + ); + + /// from: `public java.util.List installGroupsOverride` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JList? get installGroupsOverride => + _id_installGroupsOverride.get( + this, + const jni$_.JListNullableType( + jni$_.JStringNullableType())); + + /// from: `public java.util.List installGroupsOverride` + /// The returned object must be released after use, by calling the [release] method. + set installGroupsOverride(jni$_.JList? value) => + _id_installGroupsOverride.set( + this, + const jni$_.JListNullableType( + jni$_.JStringNullableType()), + value); + static final _id_new$ = _class.constructorId( r'()V', ); @@ -13150,6 +13172,28 @@ class SentryOptions extends jni$_.JObject { .check(); } + static final _id_activate = _class.instanceMethodId( + r'activate', + r'()V', + ); + + static final _activate = 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 activate()` + void activate() { + _activate(reference.pointer, _id_activate as jni$_.JMethodIDPtr).check(); + } + static final _id_addEventProcessor = _class.instanceMethodId( r'addEventProcessor', r'(Lio/sentry/EventProcessor;)V', @@ -20663,6 +20707,17 @@ class SentryReplayOptions extends jni$_.JObject { static jni$_.JString? get VIDEO_VIEW_CLASS_NAME => _id_VIDEO_VIEW_CLASS_NAME.get(_class, const jni$_.JStringNullableType()); + static final _id_CAMERAX_PREVIEW_VIEW_CLASS_NAME = _class.staticFieldId( + r'CAMERAX_PREVIEW_VIEW_CLASS_NAME', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String CAMERAX_PREVIEW_VIEW_CLASS_NAME` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get CAMERAX_PREVIEW_VIEW_CLASS_NAME => + _id_CAMERAX_PREVIEW_VIEW_CLASS_NAME.get( + _class, const jni$_.JStringNullableType()); + static final _id_ANDROIDX_MEDIA_VIEW_CLASS_NAME = _class.staticFieldId( r'ANDROIDX_MEDIA_VIEW_CLASS_NAME', r'Ljava/lang/String;', @@ -21352,6 +21407,30 @@ class SentryReplayOptions extends jni$_.JObject { .object(const jni$_.JStringNullableType()); } + static final _id_trackCustomMasking = _class.instanceMethodId( + r'trackCustomMasking', + r'()V', + ); + + static final _trackCustomMasking = 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 trackCustomMasking()` + void trackCustomMasking() { + _trackCustomMasking( + reference.pointer, _id_trackCustomMasking as jni$_.JMethodIDPtr) + .check(); + } + static final _id_isTrackConfiguration = _class.instanceMethodId( r'isTrackConfiguration', r'()Z', @@ -39233,30 +39312,6 @@ class Proxy extends jni$_.JObject { .reference); } - static final _id_type$1 = _class.instanceMethodId( - r'type', - r'()Ljava/net/Proxy$Type;', - ); - - static final _type$1 = 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.net.Proxy$Type type()` - /// The returned object must be released after use, by calling the [release] method. - Proxy$Type? type$1() { - return _type$1(reference.pointer, _id_type$1 as jni$_.JMethodIDPtr) - .object(const $Proxy$Type$NullableType()); - } - static final _id_address = _class.instanceMethodId( r'address', r'()Ljava/net/SocketAddress;', @@ -39281,30 +39336,6 @@ class Proxy extends jni$_.JObject { .object(const jni$_.JObjectNullableType()); } - static final _id_toString$1 = _class.instanceMethodId( - r'toString', - r'()Ljava/lang/String;', - ); - - static final _toString$1 = 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 toString()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? toString$1() { - return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); - } - static final _id_equals = _class.instanceMethodId( r'equals', r'(Ljava/lang/Object;)Z', @@ -39353,6 +39384,54 @@ class Proxy extends jni$_.JObject { return _hashCode$1(reference.pointer, _id_hashCode$1 as jni$_.JMethodIDPtr) .integer; } + + static final _id_toString$1 = _class.instanceMethodId( + r'toString', + r'()Ljava/lang/String;', + ); + + static final _toString$1 = 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 toString()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? toString$1() { + return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); + } + + static final _id_type$1 = _class.instanceMethodId( + r'type', + r'()Ljava/net/Proxy$Type;', + ); + + static final _type$1 = 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.net.Proxy$Type type()` + /// The returned object must be released after use, by calling the [release] method. + Proxy$Type? type$1() { + return _type$1(reference.pointer, _id_type$1 as jni$_.JMethodIDPtr) + .object(const $Proxy$Type$NullableType()); + } } final class $Proxy$NullableType extends jni$_.JObjType { @@ -39474,16 +39553,6 @@ class Bitmap$CompressFormat extends jni$_.JObject { static Bitmap$CompressFormat get WEBP => _id_WEBP.get(_class, const $Bitmap$CompressFormat$Type()); - static final _id_WEBP_LOSSY = _class.staticFieldId( - r'WEBP_LOSSY', - r'Landroid/graphics/Bitmap$CompressFormat;', - ); - - /// from: `static public final android.graphics.Bitmap$CompressFormat WEBP_LOSSY` - /// The returned object must be released after use, by calling the [release] method. - static Bitmap$CompressFormat get WEBP_LOSSY => - _id_WEBP_LOSSY.get(_class, const $Bitmap$CompressFormat$Type()); - static final _id_WEBP_LOSSLESS = _class.staticFieldId( r'WEBP_LOSSLESS', r'Landroid/graphics/Bitmap$CompressFormat;', @@ -39494,6 +39563,16 @@ class Bitmap$CompressFormat extends jni$_.JObject { static Bitmap$CompressFormat get WEBP_LOSSLESS => _id_WEBP_LOSSLESS.get(_class, const $Bitmap$CompressFormat$Type()); + static final _id_WEBP_LOSSY = _class.staticFieldId( + r'WEBP_LOSSY', + r'Landroid/graphics/Bitmap$CompressFormat;', + ); + + /// from: `static public final android.graphics.Bitmap$CompressFormat WEBP_LOSSY` + /// The returned object must be released after use, by calling the [release] method. + static Bitmap$CompressFormat get WEBP_LOSSY => + _id_WEBP_LOSSY.get(_class, const $Bitmap$CompressFormat$Type()); + static final _id_values = _class.staticMethodId( r'values', r'()[Landroid/graphics/Bitmap$CompressFormat;', @@ -39653,16 +39732,6 @@ class Bitmap$Config extends jni$_.JObject { static Bitmap$Config get ALPHA_8 => _id_ALPHA_8.get(_class, const $Bitmap$Config$Type()); - static final _id_RGB_565 = _class.staticFieldId( - r'RGB_565', - r'Landroid/graphics/Bitmap$Config;', - ); - - /// from: `static public final android.graphics.Bitmap$Config RGB_565` - /// The returned object must be released after use, by calling the [release] method. - static Bitmap$Config get RGB_565 => - _id_RGB_565.get(_class, const $Bitmap$Config$Type()); - static final _id_ARGB_4444 = _class.staticFieldId( r'ARGB_4444', r'Landroid/graphics/Bitmap$Config;', @@ -39683,16 +39752,6 @@ class Bitmap$Config extends jni$_.JObject { static Bitmap$Config get ARGB_8888 => _id_ARGB_8888.get(_class, const $Bitmap$Config$Type()); - static final _id_RGBA_F16 = _class.staticFieldId( - r'RGBA_F16', - r'Landroid/graphics/Bitmap$Config;', - ); - - /// from: `static public final android.graphics.Bitmap$Config RGBA_F16` - /// The returned object must be released after use, by calling the [release] method. - static Bitmap$Config get RGBA_F16 => - _id_RGBA_F16.get(_class, const $Bitmap$Config$Type()); - static final _id_HARDWARE = _class.staticFieldId( r'HARDWARE', r'Landroid/graphics/Bitmap$Config;', @@ -39713,6 +39772,26 @@ class Bitmap$Config extends jni$_.JObject { static Bitmap$Config get RGBA_1010102 => _id_RGBA_1010102.get(_class, const $Bitmap$Config$Type()); + static final _id_RGBA_F16 = _class.staticFieldId( + r'RGBA_F16', + r'Landroid/graphics/Bitmap$Config;', + ); + + /// from: `static public final android.graphics.Bitmap$Config RGBA_F16` + /// The returned object must be released after use, by calling the [release] method. + static Bitmap$Config get RGBA_F16 => + _id_RGBA_F16.get(_class, const $Bitmap$Config$Type()); + + static final _id_RGB_565 = _class.staticFieldId( + r'RGB_565', + r'Landroid/graphics/Bitmap$Config;', + ); + + /// from: `static public final android.graphics.Bitmap$Config RGB_565` + /// The returned object must be released after use, by calling the [release] method. + static Bitmap$Config get RGB_565 => + _id_RGB_565.get(_class, const $Bitmap$Config$Type()); + static final _id_values = _class.staticMethodId( r'values', r'()[Landroid/graphics/Bitmap$Config;', @@ -39870,135 +39949,102 @@ class Bitmap extends jni$_.JObject { /// from: `static public final int DENSITY_NONE` static const DENSITY_NONE = 0; - static final _id_getDensity = _class.instanceMethodId( - r'getDensity', - r'()I', + static final _id_asShared = _class.instanceMethodId( + r'asShared', + r'()Landroid/graphics/Bitmap;', ); - static final _getDensity = jni$_.ProtectedJniExtensions.lookup< + static final _asShared = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public int getDensity()` - int getDensity() { - return _getDensity(reference.pointer, _id_getDensity as jni$_.JMethodIDPtr) - .integer; - } - - static final _id_setDensity = _class.instanceMethodId( - r'setDensity', - r'(I)V', - ); - - static final _setDensity = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public void setDensity(int i)` - void setDensity( - int i, - ) { - _setDensity(reference.pointer, _id_setDensity as jni$_.JMethodIDPtr, i) - .check(); + /// from: `public android.graphics.Bitmap asShared()` + /// The returned object must be released after use, by calling the [release] method. + Bitmap? asShared() { + return _asShared(reference.pointer, _id_asShared as jni$_.JMethodIDPtr) + .object(const $Bitmap$NullableType()); } - static final _id_reconfigure = _class.instanceMethodId( - r'reconfigure', - r'(IILandroid/graphics/Bitmap$Config;)V', + static final _id_compress = _class.instanceMethodId( + r'compress', + r'(Landroid/graphics/Bitmap$CompressFormat;ILjava/io/OutputStream;)Z', ); - static final _reconfigure = jni$_.ProtectedJniExtensions.lookup< + static final _compress = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Int32, + jni$_.Pointer, jni$_.Int32, jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, int, jni$_.Pointer)>(); - - /// from: `public void reconfigure(int i, int i1, android.graphics.Bitmap$Config config)` - void reconfigure( - int i, - int i1, - Bitmap$Config? config, - ) { - final _$config = config?.reference ?? jni$_.jNullReference; - _reconfigure(reference.pointer, _id_reconfigure as jni$_.JMethodIDPtr, i, - i1, _$config.pointer) - .check(); - } - - static final _id_setWidth = _class.instanceMethodId( - r'setWidth', - r'(I)V', - ); - - static final _setWidth = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + )>)>>('globalEnv_CallBooleanMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + jni$_.Pointer)>(); - /// from: `public void setWidth(int i)` - void setWidth( + /// from: `public boolean compress(android.graphics.Bitmap$CompressFormat compressFormat, int i, java.io.OutputStream outputStream)` + bool compress( + Bitmap$CompressFormat? compressFormat, int i, + jni$_.JObject? outputStream, ) { - _setWidth(reference.pointer, _id_setWidth as jni$_.JMethodIDPtr, i).check(); + final _$compressFormat = compressFormat?.reference ?? jni$_.jNullReference; + final _$outputStream = outputStream?.reference ?? jni$_.jNullReference; + return _compress(reference.pointer, _id_compress as jni$_.JMethodIDPtr, + _$compressFormat.pointer, i, _$outputStream.pointer) + .boolean; } - static final _id_setHeight = _class.instanceMethodId( - r'setHeight', - r'(I)V', + static final _id_copy = _class.instanceMethodId( + r'copy', + r'(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', ); - static final _setHeight = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + static final _copy = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public void setHeight(int i)` - void setHeight( - int i, + /// from: `public android.graphics.Bitmap copy(android.graphics.Bitmap$Config config, boolean z)` + /// The returned object must be released after use, by calling the [release] method. + Bitmap? copy( + Bitmap$Config? config, + bool z, ) { - _setHeight(reference.pointer, _id_setHeight as jni$_.JMethodIDPtr, i) - .check(); + final _$config = config?.reference ?? jni$_.jNullReference; + return _copy(reference.pointer, _id_copy as jni$_.JMethodIDPtr, + _$config.pointer, z ? 1 : 0) + .object(const $Bitmap$NullableType()); } - static final _id_setConfig = _class.instanceMethodId( - r'setConfig', - r'(Landroid/graphics/Bitmap$Config;)V', + static final _id_copyPixelsFromBuffer = _class.instanceMethodId( + r'copyPixelsFromBuffer', + r'(Ljava/nio/Buffer;)V', ); - static final _setConfig = jni$_.ProtectedJniExtensions.lookup< + static final _copyPixelsFromBuffer = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -40009,85 +40055,16 @@ class Bitmap extends jni$_.JObject { jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void setConfig(android.graphics.Bitmap$Config config)` - void setConfig( - Bitmap$Config? config, + /// from: `public void copyPixelsFromBuffer(java.nio.Buffer buffer)` + void copyPixelsFromBuffer( + jni$_.JBuffer? buffer, ) { - final _$config = config?.reference ?? jni$_.jNullReference; - _setConfig(reference.pointer, _id_setConfig as jni$_.JMethodIDPtr, - _$config.pointer) + final _$buffer = buffer?.reference ?? jni$_.jNullReference; + _copyPixelsFromBuffer(reference.pointer, + _id_copyPixelsFromBuffer as jni$_.JMethodIDPtr, _$buffer.pointer) .check(); } - static final _id_recycle = _class.instanceMethodId( - r'recycle', - r'()V', - ); - - static final _recycle = 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 recycle()` - void recycle() { - _recycle(reference.pointer, _id_recycle as jni$_.JMethodIDPtr).check(); - } - - static final _id_isRecycled = _class.instanceMethodId( - r'isRecycled', - r'()Z', - ); - - static final _isRecycled = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public boolean isRecycled()` - bool isRecycled() { - return _isRecycled(reference.pointer, _id_isRecycled as jni$_.JMethodIDPtr) - .boolean; - } - - static final _id_getGenerationId = _class.instanceMethodId( - r'getGenerationId', - r'()I', - ); - - static final _getGenerationId = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public int getGenerationId()` - int getGenerationId() { - return _getGenerationId( - reference.pointer, _id_getGenerationId as jni$_.JMethodIDPtr) - .integer; - } - static final _id_copyPixelsToBuffer = _class.instanceMethodId( r'copyPixelsToBuffer', r'(Ljava/nio/Buffer;)V', @@ -40114,163 +40091,6 @@ class Bitmap extends jni$_.JObject { .check(); } - static final _id_copyPixelsFromBuffer = _class.instanceMethodId( - r'copyPixelsFromBuffer', - r'(Ljava/nio/Buffer;)V', - ); - - static final _copyPixelsFromBuffer = 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 copyPixelsFromBuffer(java.nio.Buffer buffer)` - void copyPixelsFromBuffer( - jni$_.JBuffer? buffer, - ) { - final _$buffer = buffer?.reference ?? jni$_.jNullReference; - _copyPixelsFromBuffer(reference.pointer, - _id_copyPixelsFromBuffer as jni$_.JMethodIDPtr, _$buffer.pointer) - .check(); - } - - static final _id_copy = _class.instanceMethodId( - r'copy', - r'(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', - ); - - static final _copy = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - - /// from: `public android.graphics.Bitmap copy(android.graphics.Bitmap$Config config, boolean z)` - /// The returned object must be released after use, by calling the [release] method. - Bitmap? copy( - Bitmap$Config? config, - bool z, - ) { - final _$config = config?.reference ?? jni$_.jNullReference; - return _copy(reference.pointer, _id_copy as jni$_.JMethodIDPtr, - _$config.pointer, z ? 1 : 0) - .object(const $Bitmap$NullableType()); - } - - static final _id_asShared = _class.instanceMethodId( - r'asShared', - r'()Landroid/graphics/Bitmap;', - ); - - static final _asShared = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public android.graphics.Bitmap asShared()` - /// The returned object must be released after use, by calling the [release] method. - Bitmap? asShared() { - return _asShared(reference.pointer, _id_asShared as jni$_.JMethodIDPtr) - .object(const $Bitmap$NullableType()); - } - - static final _id_wrapHardwareBuffer = _class.staticMethodId( - r'wrapHardwareBuffer', - r'(Landroid/hardware/HardwareBuffer;Landroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', - ); - - static final _wrapHardwareBuffer = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallStaticObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); - - /// from: `static public android.graphics.Bitmap wrapHardwareBuffer(android.hardware.HardwareBuffer hardwareBuffer, android.graphics.ColorSpace colorSpace)` - /// The returned object must be released after use, by calling the [release] method. - static Bitmap? wrapHardwareBuffer( - jni$_.JObject? hardwareBuffer, - jni$_.JObject? colorSpace, - ) { - final _$hardwareBuffer = hardwareBuffer?.reference ?? jni$_.jNullReference; - final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; - return _wrapHardwareBuffer( - _class.reference.pointer, - _id_wrapHardwareBuffer as jni$_.JMethodIDPtr, - _$hardwareBuffer.pointer, - _$colorSpace.pointer) - .object(const $Bitmap$NullableType()); - } - - static final _id_createScaledBitmap = _class.staticMethodId( - r'createScaledBitmap', - r'(Landroid/graphics/Bitmap;IIZ)Landroid/graphics/Bitmap;', - ); - - static final _createScaledBitmap = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallStaticObjectMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); - - /// from: `static public android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap bitmap, int i, int i1, boolean z)` - /// The returned object must be released after use, by calling the [release] method. - static Bitmap? createScaledBitmap( - Bitmap? bitmap, - int i, - int i1, - bool z, - ) { - final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; - return _createScaledBitmap( - _class.reference.pointer, - _id_createScaledBitmap as jni$_.JMethodIDPtr, - _$bitmap.pointer, - i, - i1, - z ? 1 : 0) - .object(const $Bitmap$NullableType()); - } - static final _id_createBitmap = _class.staticMethodId( r'createBitmap', r'(Landroid/graphics/Bitmap;)Landroid/graphics/Bitmap;', @@ -40407,40 +40227,34 @@ class Bitmap extends jni$_.JObject { static final _id_createBitmap$3 = _class.staticMethodId( r'createBitmap', - r'(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(Landroid/graphics/Picture;)Landroid/graphics/Bitmap;', ); static final _createBitmap$3 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Int32, - jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallStaticObjectMethod') + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallStaticObjectMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, int, jni$_.Pointer)>(); + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(android.graphics.Picture picture)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$3( - int i, - int i1, - Bitmap$Config? config, + jni$_.JObject? picture, ) { - final _$config = config?.reference ?? jni$_.jNullReference; + final _$picture = picture?.reference ?? jni$_.jNullReference; return _createBitmap$3(_class.reference.pointer, - _id_createBitmap$3 as jni$_.JMethodIDPtr, i, i1, _$config.pointer) + _id_createBitmap$3 as jni$_.JMethodIDPtr, _$picture.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$4 = _class.staticMethodId( r'createBitmap', - r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(Landroid/graphics/Picture;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$4 = jni$_.ProtectedJniExtensions.lookup< @@ -40464,20 +40278,20 @@ class Bitmap extends jni$_.JObject { int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(android.graphics.Picture picture, int i, int i1, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$4( - jni$_.JObject? displayMetrics, + jni$_.JObject? picture, int i, int i1, Bitmap$Config? config, ) { - final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; + final _$picture = picture?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; return _createBitmap$4( _class.reference.pointer, _id_createBitmap$4 as jni$_.JMethodIDPtr, - _$displayMetrics.pointer, + _$picture.pointer, i, i1, _$config.pointer) @@ -40486,7 +40300,7 @@ class Bitmap extends jni$_.JObject { static final _id_createBitmap$5 = _class.staticMethodId( r'createBitmap', - r'(IILandroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', + r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$5 = jni$_.ProtectedJniExtensions.lookup< @@ -40496,37 +40310,43 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, jni$_.Int32, jni$_.Int32, - jni$_.Pointer, - jni$_.Int32 + jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, int, jni$_.Pointer, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + int, + jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config, boolean z)` + /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$5( + jni$_.JObject? displayMetrics, int i, int i1, Bitmap$Config? config, - bool z, ) { + final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; return _createBitmap$5( _class.reference.pointer, _id_createBitmap$5 as jni$_.JMethodIDPtr, + _$displayMetrics.pointer, i, i1, - _$config.pointer, - z ? 1 : 0) + _$config.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$6 = _class.staticMethodId( r'createBitmap', - r'(IILandroid/graphics/Bitmap$Config;ZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', + r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', ); static final _createBitmap$6 = jni$_.ProtectedJniExtensions.lookup< @@ -40536,47 +40356,47 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, jni$_.Int32, jni$_.Int32, jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer + jni$_.Int32 )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, + jni$_.Pointer, int, int, jni$_.Pointer, - int, - jni$_.Pointer)>(); + int)>(); - /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config, boolean z, android.graphics.ColorSpace colorSpace)` + /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config, boolean z)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$6( + jni$_.JObject? displayMetrics, int i, int i1, Bitmap$Config? config, bool z, - jni$_.JObject? colorSpace, ) { + final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; - final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; return _createBitmap$6( _class.reference.pointer, _id_createBitmap$6 as jni$_.JMethodIDPtr, + _$displayMetrics.pointer, i, i1, _$config.pointer, - z ? 1 : 0, - _$colorSpace.pointer) + z ? 1 : 0) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$7 = _class.staticMethodId( r'createBitmap', - r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', + r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;ZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', ); static final _createBitmap$7 = jni$_.ProtectedJniExtensions.lookup< @@ -40590,7 +40410,8 @@ class Bitmap extends jni$_.JObject { jni$_.Int32, jni$_.Int32, jni$_.Pointer, - jni$_.Int32 + jni$_.Int32, + jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< jni$_.JniResult Function( @@ -40600,9 +40421,10 @@ class Bitmap extends jni$_.JObject { int, int, jni$_.Pointer, - int)>(); + int, + jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config, boolean z)` + /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config, boolean z, android.graphics.ColorSpace colorSpace)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$7( jni$_.JObject? displayMetrics, @@ -40610,9 +40432,11 @@ class Bitmap extends jni$_.JObject { int i1, Bitmap$Config? config, bool z, + jni$_.JObject? colorSpace, ) { final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; + final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; return _createBitmap$7( _class.reference.pointer, _id_createBitmap$7 as jni$_.JMethodIDPtr, @@ -40620,13 +40444,14 @@ class Bitmap extends jni$_.JObject { i, i1, _$config.pointer, - z ? 1 : 0) + z ? 1 : 0, + _$colorSpace.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$8 = _class.staticMethodId( r'createBitmap', - r'(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;ZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', + r'(Landroid/util/DisplayMetrics;[IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$8 = jni$_.ProtectedJniExtensions.lookup< @@ -40637,10 +40462,9 @@ class Bitmap extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, jni$_.Pointer, jni$_.Int32, + jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< @@ -40648,40 +40472,37 @@ class Bitmap extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - int, - int, jni$_.Pointer, int, + int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int i, int i1, android.graphics.Bitmap$Config config, boolean z, android.graphics.ColorSpace colorSpace)` + /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int[] is, int i, int i1, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$8( jni$_.JObject? displayMetrics, + jni$_.JIntArray? is$, int i, int i1, Bitmap$Config? config, - bool z, - jni$_.JObject? colorSpace, ) { final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; + final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; - final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; return _createBitmap$8( _class.reference.pointer, _id_createBitmap$8 as jni$_.JMethodIDPtr, _$displayMetrics.pointer, + _$is$.pointer, i, i1, - _$config.pointer, - z ? 1 : 0, - _$colorSpace.pointer) + _$config.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$9 = _class.staticMethodId( r'createBitmap', - r'([IIIIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(Landroid/util/DisplayMetrics;[IIIIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$9 = jni$_.ProtectedJniExtensions.lookup< @@ -40691,6 +40512,7 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, jni$_.Pointer, jni$_.Int32, jni$_.Int32, @@ -40703,15 +40525,17 @@ class Bitmap extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + jni$_.Pointer, int, int, int, int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(int[] is, int i, int i1, int i2, int i3, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int[] is, int i, int i1, int i2, int i3, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$9( + jni$_.JObject? displayMetrics, jni$_.JIntArray? is$, int i, int i1, @@ -40719,11 +40543,13 @@ class Bitmap extends jni$_.JObject { int i3, Bitmap$Config? config, ) { + final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; return _createBitmap$9( _class.reference.pointer, _id_createBitmap$9 as jni$_.JMethodIDPtr, + _$displayMetrics.pointer, _$is$.pointer, i, i1, @@ -40735,7 +40561,7 @@ class Bitmap extends jni$_.JObject { static final _id_createBitmap$10 = _class.staticMethodId( r'createBitmap', - r'(Landroid/util/DisplayMetrics;[IIIIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$10 = jni$_.ProtectedJniExtensions.lookup< @@ -40745,56 +40571,30 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, jni$_.Int32, jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - int, - int, - int, - int, - jni$_.Pointer)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, int, int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int[] is, int i, int i1, int i2, int i3, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$10( - jni$_.JObject? displayMetrics, - jni$_.JIntArray? is$, int i, int i1, - int i2, - int i3, Bitmap$Config? config, ) { - final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; - final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; - return _createBitmap$10( - _class.reference.pointer, - _id_createBitmap$10 as jni$_.JMethodIDPtr, - _$displayMetrics.pointer, - _$is$.pointer, - i, - i1, - i2, - i3, - _$config.pointer) + return _createBitmap$10(_class.reference.pointer, + _id_createBitmap$10 as jni$_.JMethodIDPtr, i, i1, _$config.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$11 = _class.staticMethodId( r'createBitmap', - r'([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(IILandroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;', ); static final _createBitmap$11 = jni$_.ProtectedJniExtensions.lookup< @@ -40804,43 +40604,37 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, jni$_.Int32, jni$_.Int32, - jni$_.Pointer + jni$_.Pointer, + jni$_.Int32 )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - int, - jni$_.Pointer)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, int, int, jni$_.Pointer, int)>(); - /// from: `static public android.graphics.Bitmap createBitmap(int[] is, int i, int i1, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config, boolean z)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$11( - jni$_.JIntArray? is$, int i, int i1, Bitmap$Config? config, + bool z, ) { - final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; return _createBitmap$11( _class.reference.pointer, _id_createBitmap$11 as jni$_.JMethodIDPtr, - _$is$.pointer, i, i1, - _$config.pointer) + _$config.pointer, + z ? 1 : 0) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$12 = _class.staticMethodId( r'createBitmap', - r'(Landroid/util/DisplayMetrics;[IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'(IILandroid/graphics/Bitmap$Config;ZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', ); static final _createBitmap$12 = jni$_.ProtectedJniExtensions.lookup< @@ -40850,75 +40644,93 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, - jni$_.Pointer, jni$_.Int32, jni$_.Int32, + jni$_.Pointer, + jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, int, int, + jni$_.Pointer, + int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.util.DisplayMetrics displayMetrics, int[] is, int i, int i1, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(int i, int i1, android.graphics.Bitmap$Config config, boolean z, android.graphics.ColorSpace colorSpace)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$12( - jni$_.JObject? displayMetrics, - jni$_.JIntArray? is$, int i, int i1, Bitmap$Config? config, + bool z, + jni$_.JObject? colorSpace, ) { - final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; - final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; + final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; return _createBitmap$12( _class.reference.pointer, _id_createBitmap$12 as jni$_.JMethodIDPtr, - _$displayMetrics.pointer, - _$is$.pointer, i, i1, - _$config.pointer) + _$config.pointer, + z ? 1 : 0, + _$colorSpace.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$13 = _class.staticMethodId( r'createBitmap', - r'(Landroid/graphics/Picture;)Landroid/graphics/Bitmap;', + r'([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$13 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallStaticObjectMethod') + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + int, + jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.graphics.Picture picture)` + /// from: `static public android.graphics.Bitmap createBitmap(int[] is, int i, int i1, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$13( - jni$_.JObject? picture, + jni$_.JIntArray? is$, + int i, + int i1, + Bitmap$Config? config, ) { - final _$picture = picture?.reference ?? jni$_.jNullReference; - return _createBitmap$13(_class.reference.pointer, - _id_createBitmap$13 as jni$_.JMethodIDPtr, _$picture.pointer) + final _$is$ = is$?.reference ?? jni$_.jNullReference; + final _$config = config?.reference ?? jni$_.jNullReference; + return _createBitmap$13( + _class.reference.pointer, + _id_createBitmap$13 as jni$_.JMethodIDPtr, + _$is$.pointer, + i, + i1, + _$config.pointer) .object(const $Bitmap$NullableType()); } static final _id_createBitmap$14 = _class.staticMethodId( r'createBitmap', - r'(Landroid/graphics/Picture;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', + r'([IIIIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;', ); static final _createBitmap$14 = jni$_.ProtectedJniExtensions.lookup< @@ -40931,6 +40743,8 @@ class Bitmap extends jni$_.JObject { jni$_.Pointer, jni$_.Int32, jni$_.Int32, + jni$_.Int32, + jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< @@ -40940,59 +40754,40 @@ class Bitmap extends jni$_.JObject { jni$_.Pointer, int, int, + int, + int, jni$_.Pointer)>(); - /// from: `static public android.graphics.Bitmap createBitmap(android.graphics.Picture picture, int i, int i1, android.graphics.Bitmap$Config config)` + /// from: `static public android.graphics.Bitmap createBitmap(int[] is, int i, int i1, int i2, int i3, android.graphics.Bitmap$Config config)` /// The returned object must be released after use, by calling the [release] method. static Bitmap? createBitmap$14( - jni$_.JObject? picture, + jni$_.JIntArray? is$, int i, int i1, + int i2, + int i3, Bitmap$Config? config, ) { - final _$picture = picture?.reference ?? jni$_.jNullReference; + final _$is$ = is$?.reference ?? jni$_.jNullReference; final _$config = config?.reference ?? jni$_.jNullReference; return _createBitmap$14( _class.reference.pointer, _id_createBitmap$14 as jni$_.JMethodIDPtr, - _$picture.pointer, + _$is$.pointer, i, i1, + i2, + i3, _$config.pointer) .object(const $Bitmap$NullableType()); } - static final _id_getNinePatchChunk = _class.instanceMethodId( - r'getNinePatchChunk', - r'()[B', - ); - - static final _getNinePatchChunk = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public byte[] getNinePatchChunk()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JByteArray? getNinePatchChunk() { - return _getNinePatchChunk( - reference.pointer, _id_getNinePatchChunk as jni$_.JMethodIDPtr) - .object(const jni$_.JByteArrayNullableType()); - } - - static final _id_compress = _class.instanceMethodId( - r'compress', - r'(Landroid/graphics/Bitmap$CompressFormat;ILjava/io/OutputStream;)Z', + static final _id_createScaledBitmap = _class.staticMethodId( + r'createScaledBitmap', + r'(Landroid/graphics/Bitmap;IIZ)Landroid/graphics/Bitmap;', ); - static final _compress = jni$_.ProtectedJniExtensions.lookup< + static final _createScaledBitmap = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -41001,82 +40796,62 @@ class Bitmap extends jni$_.JObject { ( jni$_.Pointer, jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallStaticObjectMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - jni$_.Pointer)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); - /// from: `public boolean compress(android.graphics.Bitmap$CompressFormat compressFormat, int i, java.io.OutputStream outputStream)` - bool compress( - Bitmap$CompressFormat? compressFormat, + /// from: `static public android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap bitmap, int i, int i1, boolean z)` + /// The returned object must be released after use, by calling the [release] method. + static Bitmap? createScaledBitmap( + Bitmap? bitmap, int i, - jni$_.JObject? outputStream, + int i1, + bool z, ) { - final _$compressFormat = compressFormat?.reference ?? jni$_.jNullReference; - final _$outputStream = outputStream?.reference ?? jni$_.jNullReference; - return _compress(reference.pointer, _id_compress as jni$_.JMethodIDPtr, - _$compressFormat.pointer, i, _$outputStream.pointer) - .boolean; + final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; + return _createScaledBitmap( + _class.reference.pointer, + _id_createScaledBitmap as jni$_.JMethodIDPtr, + _$bitmap.pointer, + i, + i1, + z ? 1 : 0) + .object(const $Bitmap$NullableType()); } - static final _id_isMutable = _class.instanceMethodId( - r'isMutable', - r'()Z', + static final _id_describeContents = _class.instanceMethodId( + r'describeContents', + r'()I', ); - static final _isMutable = jni$_.ProtectedJniExtensions.lookup< + static final _describeContents = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + )>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public boolean isMutable()` - bool isMutable() { - return _isMutable(reference.pointer, _id_isMutable as jni$_.JMethodIDPtr) - .boolean; - } - - static final _id_isPremultiplied = _class.instanceMethodId( - r'isPremultiplied', - r'()Z', - ); - - static final _isPremultiplied = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public boolean isPremultiplied()` - bool isPremultiplied() { - return _isPremultiplied( - reference.pointer, _id_isPremultiplied as jni$_.JMethodIDPtr) - .boolean; + /// from: `public int describeContents()` + int describeContents() { + return _describeContents( + reference.pointer, _id_describeContents as jni$_.JMethodIDPtr) + .integer; } - static final _id_setPremultiplied = _class.instanceMethodId( - r'setPremultiplied', - r'(Z)V', + static final _id_eraseColor = _class.instanceMethodId( + r'eraseColor', + r'(I)V', ); - static final _setPremultiplied = jni$_.ProtectedJniExtensions.lookup< + static final _eraseColor = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -41086,223 +40861,106 @@ class Bitmap extends jni$_.JObject { jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public void setPremultiplied(boolean z)` - void setPremultiplied( - bool z, + /// from: `public void eraseColor(int i)` + void eraseColor( + int i, ) { - _setPremultiplied(reference.pointer, - _id_setPremultiplied as jni$_.JMethodIDPtr, z ? 1 : 0) + _eraseColor(reference.pointer, _id_eraseColor as jni$_.JMethodIDPtr, i) .check(); } - static final _id_getWidth = _class.instanceMethodId( - r'getWidth', - r'()I', + static final _id_eraseColor$1 = _class.instanceMethodId( + r'eraseColor', + r'(J)V', ); - static final _getWidth = jni$_.ProtectedJniExtensions.lookup< + static final _eraseColor$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public int getWidth()` - int getWidth() { - return _getWidth(reference.pointer, _id_getWidth as jni$_.JMethodIDPtr) - .integer; + /// from: `public void eraseColor(long j)` + void eraseColor$1( + int j, + ) { + _eraseColor$1(reference.pointer, _id_eraseColor$1 as jni$_.JMethodIDPtr, j) + .check(); } - static final _id_getHeight = _class.instanceMethodId( - r'getHeight', - r'()I', + static final _id_extractAlpha = _class.instanceMethodId( + r'extractAlpha', + r'()Landroid/graphics/Bitmap;', ); - static final _getHeight = jni$_.ProtectedJniExtensions.lookup< + static final _extractAlpha = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public int getHeight()` - int getHeight() { - return _getHeight(reference.pointer, _id_getHeight as jni$_.JMethodIDPtr) - .integer; - } - - static final _id_getScaledWidth = _class.instanceMethodId( - r'getScaledWidth', - r'(Landroid/graphics/Canvas;)I', - ); - - static final _getScaledWidth = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); - - /// from: `public int getScaledWidth(android.graphics.Canvas canvas)` - int getScaledWidth( - jni$_.JObject? canvas, - ) { - final _$canvas = canvas?.reference ?? jni$_.jNullReference; - return _getScaledWidth(reference.pointer, - _id_getScaledWidth as jni$_.JMethodIDPtr, _$canvas.pointer) - .integer; - } - - static final _id_getScaledHeight = _class.instanceMethodId( - r'getScaledHeight', - r'(Landroid/graphics/Canvas;)I', - ); - - static final _getScaledHeight = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); - - /// from: `public int getScaledHeight(android.graphics.Canvas canvas)` - int getScaledHeight( - jni$_.JObject? canvas, - ) { - final _$canvas = canvas?.reference ?? jni$_.jNullReference; - return _getScaledHeight(reference.pointer, - _id_getScaledHeight as jni$_.JMethodIDPtr, _$canvas.pointer) - .integer; - } - - static final _id_getScaledWidth$1 = _class.instanceMethodId( - r'getScaledWidth', - r'(Landroid/util/DisplayMetrics;)I', - ); - - static final _getScaledWidth$1 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); - - /// from: `public int getScaledWidth(android.util.DisplayMetrics displayMetrics)` - int getScaledWidth$1( - jni$_.JObject? displayMetrics, - ) { - final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; - return _getScaledWidth$1( - reference.pointer, - _id_getScaledWidth$1 as jni$_.JMethodIDPtr, - _$displayMetrics.pointer) - .integer; - } - - static final _id_getScaledHeight$1 = _class.instanceMethodId( - r'getScaledHeight', - r'(Landroid/util/DisplayMetrics;)I', - ); - - static final _getScaledHeight$1 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); - - /// from: `public int getScaledHeight(android.util.DisplayMetrics displayMetrics)` - int getScaledHeight$1( - jni$_.JObject? displayMetrics, - ) { - final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; - return _getScaledHeight$1( - reference.pointer, - _id_getScaledHeight$1 as jni$_.JMethodIDPtr, - _$displayMetrics.pointer) - .integer; - } - - static final _id_getScaledWidth$2 = _class.instanceMethodId( - r'getScaledWidth', - r'(I)I', - ); - - static final _getScaledWidth$2 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public int getScaledWidth(int i)` - int getScaledWidth$2( - int i, - ) { - return _getScaledWidth$2( - reference.pointer, _id_getScaledWidth$2 as jni$_.JMethodIDPtr, i) - .integer; + /// from: `public android.graphics.Bitmap extractAlpha()` + /// The returned object must be released after use, by calling the [release] method. + Bitmap? extractAlpha() { + return _extractAlpha( + reference.pointer, _id_extractAlpha as jni$_.JMethodIDPtr) + .object(const $Bitmap$NullableType()); } - static final _id_getScaledHeight$2 = _class.instanceMethodId( - r'getScaledHeight', - r'(I)I', + static final _id_extractAlpha$1 = _class.instanceMethodId( + r'extractAlpha', + r'(Landroid/graphics/Paint;[I)Landroid/graphics/Bitmap;', ); - static final _getScaledHeight$2 = jni$_.ProtectedJniExtensions.lookup< + static final _extractAlpha$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public int getScaledHeight(int i)` - int getScaledHeight$2( - int i, + /// from: `public android.graphics.Bitmap extractAlpha(android.graphics.Paint paint, int[] is)` + /// The returned object must be released after use, by calling the [release] method. + Bitmap? extractAlpha$1( + jni$_.JObject? paint, + jni$_.JIntArray? is$, ) { - return _getScaledHeight$2( - reference.pointer, _id_getScaledHeight$2 as jni$_.JMethodIDPtr, i) - .integer; + final _$paint = paint?.reference ?? jni$_.jNullReference; + final _$is$ = is$?.reference ?? jni$_.jNullReference; + return _extractAlpha$1( + reference.pointer, + _id_extractAlpha$1 as jni$_.JMethodIDPtr, + _$paint.pointer, + _$is$.pointer) + .object(const $Bitmap$NullableType()); } - static final _id_getRowBytes = _class.instanceMethodId( - r'getRowBytes', + static final _id_getAllocationByteCount = _class.instanceMethodId( + r'getAllocationByteCount', r'()I', ); - static final _getRowBytes = jni$_.ProtectedJniExtensions.lookup< + static final _getAllocationByteCount = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -41314,10 +40972,10 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public int getRowBytes()` - int getRowBytes() { - return _getRowBytes( - reference.pointer, _id_getRowBytes as jni$_.JMethodIDPtr) + /// from: `public int getAllocationByteCount()` + int getAllocationByteCount() { + return _getAllocationByteCount( + reference.pointer, _id_getAllocationByteCount as jni$_.JMethodIDPtr) .integer; } @@ -41345,28 +41003,56 @@ class Bitmap extends jni$_.JObject { .integer; } - static final _id_getAllocationByteCount = _class.instanceMethodId( - r'getAllocationByteCount', - r'()I', + static final _id_getColor = _class.instanceMethodId( + r'getColor', + r'(II)Landroid/graphics/Color;', ); - static final _getAllocationByteCount = jni$_.ProtectedJniExtensions.lookup< + static final _getColor = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32, jni$_.Int32)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int, int)>(); + + /// from: `public android.graphics.Color getColor(int i, int i1)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getColor( + int i, + int i1, + ) { + return _getColor( + reference.pointer, _id_getColor as jni$_.JMethodIDPtr, i, i1) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_getColorSpace = _class.instanceMethodId( + r'getColorSpace', + r'()Landroid/graphics/ColorSpace;', + ); + + static final _getColorSpace = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public int getAllocationByteCount()` - int getAllocationByteCount() { - return _getAllocationByteCount( - reference.pointer, _id_getAllocationByteCount as jni$_.JMethodIDPtr) - .integer; + /// from: `public android.graphics.ColorSpace getColorSpace()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getColorSpace() { + return _getColorSpace( + reference.pointer, _id_getColorSpace as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } static final _id_getConfig = _class.instanceMethodId( @@ -41393,106 +41079,83 @@ class Bitmap extends jni$_.JObject { .object(const $Bitmap$Config$NullableType()); } - static final _id_hasAlpha = _class.instanceMethodId( - r'hasAlpha', - r'()Z', + static final _id_getDensity = _class.instanceMethodId( + r'getDensity', + r'()I', ); - static final _hasAlpha = jni$_.ProtectedJniExtensions.lookup< + static final _getDensity = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + )>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public boolean hasAlpha()` - bool hasAlpha() { - return _hasAlpha(reference.pointer, _id_hasAlpha as jni$_.JMethodIDPtr) - .boolean; - } - - static final _id_setHasAlpha = _class.instanceMethodId( - r'setHasAlpha', - r'(Z)V', - ); - - static final _setHasAlpha = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public void setHasAlpha(boolean z)` - void setHasAlpha( - bool z, - ) { - _setHasAlpha( - reference.pointer, _id_setHasAlpha as jni$_.JMethodIDPtr, z ? 1 : 0) - .check(); + /// from: `public int getDensity()` + int getDensity() { + return _getDensity(reference.pointer, _id_getDensity as jni$_.JMethodIDPtr) + .integer; } - static final _id_hasMipMap = _class.instanceMethodId( - r'hasMipMap', - r'()Z', + static final _id_getGainmap = _class.instanceMethodId( + r'getGainmap', + r'()Landroid/graphics/Gainmap;', ); - static final _hasMipMap = jni$_.ProtectedJniExtensions.lookup< + static final _getGainmap = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public boolean hasMipMap()` - bool hasMipMap() { - return _hasMipMap(reference.pointer, _id_hasMipMap as jni$_.JMethodIDPtr) - .boolean; + /// from: `public android.graphics.Gainmap getGainmap()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getGainmap() { + return _getGainmap(reference.pointer, _id_getGainmap as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_setHasMipMap = _class.instanceMethodId( - r'setHasMipMap', - r'(Z)V', + static final _id_getGenerationId = _class.instanceMethodId( + r'getGenerationId', + r'()I', ); - static final _setHasMipMap = jni$_.ProtectedJniExtensions.lookup< + static final _getGenerationId = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void setHasMipMap(boolean z)` - void setHasMipMap( - bool z, - ) { - _setHasMipMap(reference.pointer, _id_setHasMipMap as jni$_.JMethodIDPtr, - z ? 1 : 0) - .check(); + /// from: `public int getGenerationId()` + int getGenerationId() { + return _getGenerationId( + reference.pointer, _id_getGenerationId as jni$_.JMethodIDPtr) + .integer; } - static final _id_getColorSpace = _class.instanceMethodId( - r'getColorSpace', - r'()Landroid/graphics/ColorSpace;', + static final _id_getHardwareBuffer = _class.instanceMethodId( + r'getHardwareBuffer', + r'()Landroid/hardware/HardwareBuffer;', ); - static final _getColorSpace = jni$_.ProtectedJniExtensions.lookup< + static final _getHardwareBuffer = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -41504,69 +41167,43 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public android.graphics.ColorSpace getColorSpace()` + /// from: `public android.hardware.HardwareBuffer getHardwareBuffer()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getColorSpace() { - return _getColorSpace( - reference.pointer, _id_getColorSpace as jni$_.JMethodIDPtr) + jni$_.JObject? getHardwareBuffer() { + return _getHardwareBuffer( + reference.pointer, _id_getHardwareBuffer as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_setColorSpace = _class.instanceMethodId( - r'setColorSpace', - r'(Landroid/graphics/ColorSpace;)V', - ); - - static final _setColorSpace = 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 setColorSpace(android.graphics.ColorSpace colorSpace)` - void setColorSpace( - jni$_.JObject? colorSpace, - ) { - final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; - _setColorSpace(reference.pointer, _id_setColorSpace as jni$_.JMethodIDPtr, - _$colorSpace.pointer) - .check(); - } - - static final _id_hasGainmap = _class.instanceMethodId( - r'hasGainmap', - r'()Z', + static final _id_getHeight = _class.instanceMethodId( + r'getHeight', + r'()I', ); - static final _hasGainmap = jni$_.ProtectedJniExtensions.lookup< + static final _getHeight = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + )>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public boolean hasGainmap()` - bool hasGainmap() { - return _hasGainmap(reference.pointer, _id_hasGainmap as jni$_.JMethodIDPtr) - .boolean; + /// from: `public int getHeight()` + int getHeight() { + return _getHeight(reference.pointer, _id_getHeight as jni$_.JMethodIDPtr) + .integer; } - static final _id_getGainmap = _class.instanceMethodId( - r'getGainmap', - r'()Landroid/graphics/Gainmap;', + static final _id_getNinePatchChunk = _class.instanceMethodId( + r'getNinePatchChunk', + r'()[B', ); - static final _getGainmap = jni$_.ProtectedJniExtensions.lookup< + static final _getNinePatchChunk = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -41578,93 +41215,22 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public android.graphics.Gainmap getGainmap()` + /// from: `public byte[] getNinePatchChunk()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getGainmap() { - return _getGainmap(reference.pointer, _id_getGainmap as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + jni$_.JByteArray? getNinePatchChunk() { + return _getNinePatchChunk( + reference.pointer, _id_getNinePatchChunk as jni$_.JMethodIDPtr) + .object(const jni$_.JByteArrayNullableType()); } - static final _id_setGainmap = _class.instanceMethodId( - r'setGainmap', - r'(Landroid/graphics/Gainmap;)V', + static final _id_getPixel = _class.instanceMethodId( + r'getPixel', + r'(II)I', ); - static final _setGainmap = jni$_.ProtectedJniExtensions.lookup< + static final _getPixel = 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 setGainmap(android.graphics.Gainmap gainmap)` - void setGainmap( - jni$_.JObject? gainmap, - ) { - final _$gainmap = gainmap?.reference ?? jni$_.jNullReference; - _setGainmap(reference.pointer, _id_setGainmap as jni$_.JMethodIDPtr, - _$gainmap.pointer) - .check(); - } - - static final _id_eraseColor = _class.instanceMethodId( - r'eraseColor', - r'(I)V', - ); - - static final _eraseColor = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public void eraseColor(int i)` - void eraseColor( - int i, - ) { - _eraseColor(reference.pointer, _id_eraseColor as jni$_.JMethodIDPtr, i) - .check(); - } - - static final _id_eraseColor$1 = _class.instanceMethodId( - r'eraseColor', - r'(J)V', - ); - - static final _eraseColor$1 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public void eraseColor(long j)` - void eraseColor$1( - int j, - ) { - _eraseColor$1(reference.pointer, _id_eraseColor$1 as jni$_.JMethodIDPtr, j) - .check(); - } - - static final _id_getPixel = _class.instanceMethodId( - r'getPixel', - r'(II)I', - ); - - static final _getPixel = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32, jni$_.Int32)>)>>( @@ -41683,33 +41249,6 @@ class Bitmap extends jni$_.JObject { .integer; } - static final _id_getColor = _class.instanceMethodId( - r'getColor', - r'(II)Landroid/graphics/Color;', - ); - - static final _getColor = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32, jni$_.Int32)>)>>( - 'globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int, int)>(); - - /// from: `public android.graphics.Color getColor(int i, int i1)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getColor( - int i, - int i1, - ) { - return _getColor( - reference.pointer, _id_getColor as jni$_.JMethodIDPtr, i, i1) - .object(const jni$_.JObjectNullableType()); - } - static final _id_getPixels = _class.instanceMethodId( r'getPixels', r'([IIIIIII)V', @@ -41758,86 +41297,192 @@ class Bitmap extends jni$_.JObject { .check(); } - static final _id_setPixel = _class.instanceMethodId( - r'setPixel', - r'(III)V', + static final _id_getRowBytes = _class.instanceMethodId( + r'getRowBytes', + r'()I', ); - static final _setPixel = jni$_.ProtectedJniExtensions.lookup< + static final _getRowBytes = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public int getRowBytes()` + int getRowBytes() { + return _getRowBytes( + reference.pointer, _id_getRowBytes as jni$_.JMethodIDPtr) + .integer; + } + + static final _id_getScaledHeight = _class.instanceMethodId( + r'getScaledHeight', + r'(Landroid/graphics/Canvas;)I', + ); + + static final _getScaledHeight = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32, jni$_.Int32, jni$_.Int32)>)>>( - 'globalEnv_CallVoidMethod') + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int, int, int)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void setPixel(int i, int i1, int i2)` - void setPixel( + /// from: `public int getScaledHeight(android.graphics.Canvas canvas)` + int getScaledHeight( + jni$_.JObject? canvas, + ) { + final _$canvas = canvas?.reference ?? jni$_.jNullReference; + return _getScaledHeight(reference.pointer, + _id_getScaledHeight as jni$_.JMethodIDPtr, _$canvas.pointer) + .integer; + } + + static final _id_getScaledHeight$1 = _class.instanceMethodId( + r'getScaledHeight', + r'(Landroid/util/DisplayMetrics;)I', + ); + + static final _getScaledHeight$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public int getScaledHeight(android.util.DisplayMetrics displayMetrics)` + int getScaledHeight$1( + jni$_.JObject? displayMetrics, + ) { + final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; + return _getScaledHeight$1( + reference.pointer, + _id_getScaledHeight$1 as jni$_.JMethodIDPtr, + _$displayMetrics.pointer) + .integer; + } + + static final _id_getScaledHeight$2 = _class.instanceMethodId( + r'getScaledHeight', + r'(I)I', + ); + + static final _getScaledHeight$2 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public int getScaledHeight(int i)` + int getScaledHeight$2( int i, - int i1, - int i2, ) { - _setPixel(reference.pointer, _id_setPixel as jni$_.JMethodIDPtr, i, i1, i2) - .check(); + return _getScaledHeight$2( + reference.pointer, _id_getScaledHeight$2 as jni$_.JMethodIDPtr, i) + .integer; } - static final _id_setPixels = _class.instanceMethodId( - r'setPixels', - r'([IIIIIII)V', + static final _id_getScaledWidth = _class.instanceMethodId( + r'getScaledWidth', + r'(Landroid/graphics/Canvas;)I', ); - static final _setPixels = jni$_.ProtectedJniExtensions.lookup< + static final _getScaledWidth = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public int getScaledWidth(android.graphics.Canvas canvas)` + int getScaledWidth( + jni$_.JObject? canvas, + ) { + final _$canvas = canvas?.reference ?? jni$_.jNullReference; + return _getScaledWidth(reference.pointer, + _id_getScaledWidth as jni$_.JMethodIDPtr, _$canvas.pointer) + .integer; + } + + static final _id_getScaledWidth$1 = _class.instanceMethodId( + r'getScaledWidth', + r'(Landroid/util/DisplayMetrics;)I', + ); + + static final _getScaledWidth$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public int getScaledWidth(android.util.DisplayMetrics displayMetrics)` + int getScaledWidth$1( + jni$_.JObject? displayMetrics, + ) { + final _$displayMetrics = displayMetrics?.reference ?? jni$_.jNullReference; + return _getScaledWidth$1( + reference.pointer, + _id_getScaledWidth$1 as jni$_.JMethodIDPtr, + _$displayMetrics.pointer) + .integer; + } + + static final _id_getScaledWidth$2 = _class.instanceMethodId( + r'getScaledWidth', + r'(I)I', + ); + + static final _getScaledWidth$2 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallVoidMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - int, - int, - int, - int, - int)>(); + jni$_.JniResult Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public void setPixels(int[] is, int i, int i1, int i2, int i3, int i4, int i5)` - void setPixels( - jni$_.JIntArray? is$, + /// from: `public int getScaledWidth(int i)` + int getScaledWidth$2( int i, - int i1, - int i2, - int i3, - int i4, - int i5, ) { - final _$is$ = is$?.reference ?? jni$_.jNullReference; - _setPixels(reference.pointer, _id_setPixels as jni$_.JMethodIDPtr, - _$is$.pointer, i, i1, i2, i3, i4, i5) - .check(); + return _getScaledWidth$2( + reference.pointer, _id_getScaledWidth$2 as jni$_.JMethodIDPtr, i) + .integer; } - static final _id_describeContents = _class.instanceMethodId( - r'describeContents', + static final _id_getWidth = _class.instanceMethodId( + r'getWidth', r'()I', ); - static final _describeContents = jni$_.ProtectedJniExtensions.lookup< + static final _getWidth = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -41849,186 +41494,620 @@ class Bitmap extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public int describeContents()` - int describeContents() { - return _describeContents( - reference.pointer, _id_describeContents as jni$_.JMethodIDPtr) + /// from: `public int getWidth()` + int getWidth() { + return _getWidth(reference.pointer, _id_getWidth as jni$_.JMethodIDPtr) .integer; } - static final _id_writeToParcel = _class.instanceMethodId( - r'writeToParcel', - r'(Landroid/os/Parcel;I)V', + static final _id_hasAlpha = _class.instanceMethodId( + r'hasAlpha', + r'()Z', ); - static final _writeToParcel = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallVoidMethod') + static final _hasAlpha = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void writeToParcel(android.os.Parcel parcel, int i)` - void writeToParcel( - jni$_.JObject? parcel, - int i, - ) { - final _$parcel = parcel?.reference ?? jni$_.jNullReference; - _writeToParcel(reference.pointer, _id_writeToParcel as jni$_.JMethodIDPtr, - _$parcel.pointer, i) - .check(); + /// from: `public boolean hasAlpha()` + bool hasAlpha() { + return _hasAlpha(reference.pointer, _id_hasAlpha as jni$_.JMethodIDPtr) + .boolean; } - static final _id_extractAlpha = _class.instanceMethodId( - r'extractAlpha', - r'()Landroid/graphics/Bitmap;', + static final _id_hasGainmap = _class.instanceMethodId( + r'hasGainmap', + r'()Z', ); - static final _extractAlpha = jni$_.ProtectedJniExtensions.lookup< + static final _hasGainmap = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + )>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public android.graphics.Bitmap extractAlpha()` - /// The returned object must be released after use, by calling the [release] method. - Bitmap? extractAlpha() { - return _extractAlpha( - reference.pointer, _id_extractAlpha as jni$_.JMethodIDPtr) - .object(const $Bitmap$NullableType()); + /// from: `public boolean hasGainmap()` + bool hasGainmap() { + return _hasGainmap(reference.pointer, _id_hasGainmap as jni$_.JMethodIDPtr) + .boolean; } - static final _id_extractAlpha$1 = _class.instanceMethodId( - r'extractAlpha', - r'(Landroid/graphics/Paint;[I)Landroid/graphics/Bitmap;', + static final _id_hasMipMap = _class.instanceMethodId( + r'hasMipMap', + r'()Z', ); - static final _extractAlpha$1 = jni$_.ProtectedJniExtensions.lookup< + static final _hasMipMap = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public android.graphics.Bitmap extractAlpha(android.graphics.Paint paint, int[] is)` - /// The returned object must be released after use, by calling the [release] method. - Bitmap? extractAlpha$1( - jni$_.JObject? paint, - jni$_.JIntArray? is$, - ) { - final _$paint = paint?.reference ?? jni$_.jNullReference; - final _$is$ = is$?.reference ?? jni$_.jNullReference; - return _extractAlpha$1( - reference.pointer, - _id_extractAlpha$1 as jni$_.JMethodIDPtr, - _$paint.pointer, - _$is$.pointer) - .object(const $Bitmap$NullableType()); + /// from: `public boolean hasMipMap()` + bool hasMipMap() { + return _hasMipMap(reference.pointer, _id_hasMipMap as jni$_.JMethodIDPtr) + .boolean; } - static final _id_sameAs = _class.instanceMethodId( - r'sameAs', - r'(Landroid/graphics/Bitmap;)Z', + static final _id_isMutable = _class.instanceMethodId( + r'isMutable', + r'()Z', ); - static final _sameAs = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallBooleanMethod') + static final _isMutable = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public boolean sameAs(android.graphics.Bitmap bitmap)` - bool sameAs( - Bitmap? bitmap, - ) { - final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; - return _sameAs(reference.pointer, _id_sameAs as jni$_.JMethodIDPtr, - _$bitmap.pointer) + /// from: `public boolean isMutable()` + bool isMutable() { + return _isMutable(reference.pointer, _id_isMutable as jni$_.JMethodIDPtr) .boolean; } - static final _id_prepareToDraw = _class.instanceMethodId( - r'prepareToDraw', - r'()V', + static final _id_isPremultiplied = _class.instanceMethodId( + r'isPremultiplied', + r'()Z', ); - static final _prepareToDraw = jni$_.ProtectedJniExtensions.lookup< + static final _isPremultiplied = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallVoidMethod') + )>>('globalEnv_CallBooleanMethod') .asFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public void prepareToDraw()` - void prepareToDraw() { - _prepareToDraw(reference.pointer, _id_prepareToDraw as jni$_.JMethodIDPtr) - .check(); + /// from: `public boolean isPremultiplied()` + bool isPremultiplied() { + return _isPremultiplied( + reference.pointer, _id_isPremultiplied as jni$_.JMethodIDPtr) + .boolean; } - static final _id_getHardwareBuffer = _class.instanceMethodId( - r'getHardwareBuffer', - r'()Landroid/hardware/HardwareBuffer;', + static final _id_isRecycled = _class.instanceMethodId( + r'isRecycled', + r'()Z', ); - static final _getHardwareBuffer = jni$_.ProtectedJniExtensions.lookup< + static final _isRecycled = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + )>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public android.hardware.HardwareBuffer getHardwareBuffer()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getHardwareBuffer() { - return _getHardwareBuffer( - reference.pointer, _id_getHardwareBuffer as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean isRecycled()` + bool isRecycled() { + return _isRecycled(reference.pointer, _id_isRecycled as jni$_.JMethodIDPtr) + .boolean; } -} -final class $Bitmap$NullableType extends jni$_.JObjType { - @jni$_.internal - const $Bitmap$NullableType(); + static final _id_prepareToDraw = _class.instanceMethodId( + r'prepareToDraw', + r'()V', + ); - @jni$_.internal - @core$_.override - String get signature => r'Landroid/graphics/Bitmap;'; + static final _prepareToDraw = 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 prepareToDraw()` + void prepareToDraw() { + _prepareToDraw(reference.pointer, _id_prepareToDraw as jni$_.JMethodIDPtr) + .check(); + } + + static final _id_reconfigure = _class.instanceMethodId( + r'reconfigure', + r'(IILandroid/graphics/Bitmap$Config;)V', + ); + + static final _reconfigure = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Int32, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, int, int, jni$_.Pointer)>(); + + /// from: `public void reconfigure(int i, int i1, android.graphics.Bitmap$Config config)` + void reconfigure( + int i, + int i1, + Bitmap$Config? config, + ) { + final _$config = config?.reference ?? jni$_.jNullReference; + _reconfigure(reference.pointer, _id_reconfigure as jni$_.JMethodIDPtr, i, + i1, _$config.pointer) + .check(); + } + + static final _id_recycle = _class.instanceMethodId( + r'recycle', + r'()V', + ); + + static final _recycle = 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 recycle()` + void recycle() { + _recycle(reference.pointer, _id_recycle as jni$_.JMethodIDPtr).check(); + } + + static final _id_sameAs = _class.instanceMethodId( + r'sameAs', + r'(Landroid/graphics/Bitmap;)Z', + ); + + static final _sameAs = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public boolean sameAs(android.graphics.Bitmap bitmap)` + bool sameAs( + Bitmap? bitmap, + ) { + final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; + return _sameAs(reference.pointer, _id_sameAs as jni$_.JMethodIDPtr, + _$bitmap.pointer) + .boolean; + } + + static final _id_setColorSpace = _class.instanceMethodId( + r'setColorSpace', + r'(Landroid/graphics/ColorSpace;)V', + ); + + static final _setColorSpace = 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 setColorSpace(android.graphics.ColorSpace colorSpace)` + void setColorSpace( + jni$_.JObject? colorSpace, + ) { + final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; + _setColorSpace(reference.pointer, _id_setColorSpace as jni$_.JMethodIDPtr, + _$colorSpace.pointer) + .check(); + } + + static final _id_setConfig = _class.instanceMethodId( + r'setConfig', + r'(Landroid/graphics/Bitmap$Config;)V', + ); + + static final _setConfig = 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 setConfig(android.graphics.Bitmap$Config config)` + void setConfig( + Bitmap$Config? config, + ) { + final _$config = config?.reference ?? jni$_.jNullReference; + _setConfig(reference.pointer, _id_setConfig as jni$_.JMethodIDPtr, + _$config.pointer) + .check(); + } + + static final _id_setDensity = _class.instanceMethodId( + r'setDensity', + r'(I)V', + ); + + static final _setDensity = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setDensity(int i)` + void setDensity( + int i, + ) { + _setDensity(reference.pointer, _id_setDensity as jni$_.JMethodIDPtr, i) + .check(); + } + + static final _id_setGainmap = _class.instanceMethodId( + r'setGainmap', + r'(Landroid/graphics/Gainmap;)V', + ); + + static final _setGainmap = 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 setGainmap(android.graphics.Gainmap gainmap)` + void setGainmap( + jni$_.JObject? gainmap, + ) { + final _$gainmap = gainmap?.reference ?? jni$_.jNullReference; + _setGainmap(reference.pointer, _id_setGainmap as jni$_.JMethodIDPtr, + _$gainmap.pointer) + .check(); + } + + static final _id_setHasAlpha = _class.instanceMethodId( + r'setHasAlpha', + r'(Z)V', + ); + + static final _setHasAlpha = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setHasAlpha(boolean z)` + void setHasAlpha( + bool z, + ) { + _setHasAlpha( + reference.pointer, _id_setHasAlpha as jni$_.JMethodIDPtr, z ? 1 : 0) + .check(); + } + + static final _id_setHasMipMap = _class.instanceMethodId( + r'setHasMipMap', + r'(Z)V', + ); + + static final _setHasMipMap = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setHasMipMap(boolean z)` + void setHasMipMap( + bool z, + ) { + _setHasMipMap(reference.pointer, _id_setHasMipMap as jni$_.JMethodIDPtr, + z ? 1 : 0) + .check(); + } + + static final _id_setHeight = _class.instanceMethodId( + r'setHeight', + r'(I)V', + ); + + static final _setHeight = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setHeight(int i)` + void setHeight( + int i, + ) { + _setHeight(reference.pointer, _id_setHeight as jni$_.JMethodIDPtr, i) + .check(); + } + + static final _id_setPixel = _class.instanceMethodId( + r'setPixel', + r'(III)V', + ); + + static final _setPixel = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32, jni$_.Int32, jni$_.Int32)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int, int, int)>(); + + /// from: `public void setPixel(int i, int i1, int i2)` + void setPixel( + int i, + int i1, + int i2, + ) { + _setPixel(reference.pointer, _id_setPixel as jni$_.JMethodIDPtr, i, i1, i2) + .check(); + } + + static final _id_setPixels = _class.instanceMethodId( + r'setPixels', + r'([IIIIIII)V', + ); + + static final _setPixels = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + int, + int, + int, + int, + int)>(); + + /// from: `public void setPixels(int[] is, int i, int i1, int i2, int i3, int i4, int i5)` + void setPixels( + jni$_.JIntArray? is$, + int i, + int i1, + int i2, + int i3, + int i4, + int i5, + ) { + final _$is$ = is$?.reference ?? jni$_.jNullReference; + _setPixels(reference.pointer, _id_setPixels as jni$_.JMethodIDPtr, + _$is$.pointer, i, i1, i2, i3, i4, i5) + .check(); + } + + static final _id_setPremultiplied = _class.instanceMethodId( + r'setPremultiplied', + r'(Z)V', + ); + + static final _setPremultiplied = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setPremultiplied(boolean z)` + void setPremultiplied( + bool z, + ) { + _setPremultiplied(reference.pointer, + _id_setPremultiplied as jni$_.JMethodIDPtr, z ? 1 : 0) + .check(); + } + + static final _id_setWidth = _class.instanceMethodId( + r'setWidth', + r'(I)V', + ); + + static final _setWidth = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + + /// from: `public void setWidth(int i)` + void setWidth( + int i, + ) { + _setWidth(reference.pointer, _id_setWidth as jni$_.JMethodIDPtr, i).check(); + } + + static final _id_wrapHardwareBuffer = _class.staticMethodId( + r'wrapHardwareBuffer', + r'(Landroid/hardware/HardwareBuffer;Landroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;', + ); + + static final _wrapHardwareBuffer = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallStaticObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); + + /// from: `static public android.graphics.Bitmap wrapHardwareBuffer(android.hardware.HardwareBuffer hardwareBuffer, android.graphics.ColorSpace colorSpace)` + /// The returned object must be released after use, by calling the [release] method. + static Bitmap? wrapHardwareBuffer( + jni$_.JObject? hardwareBuffer, + jni$_.JObject? colorSpace, + ) { + final _$hardwareBuffer = hardwareBuffer?.reference ?? jni$_.jNullReference; + final _$colorSpace = colorSpace?.reference ?? jni$_.jNullReference; + return _wrapHardwareBuffer( + _class.reference.pointer, + _id_wrapHardwareBuffer as jni$_.JMethodIDPtr, + _$hardwareBuffer.pointer, + _$colorSpace.pointer) + .object(const $Bitmap$NullableType()); + } + + static final _id_writeToParcel = _class.instanceMethodId( + r'writeToParcel', + r'(Landroid/os/Parcel;I)V', + ); + + static final _writeToParcel = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + + /// from: `public void writeToParcel(android.os.Parcel parcel, int i)` + void writeToParcel( + jni$_.JObject? parcel, + int i, + ) { + final _$parcel = parcel?.reference ?? jni$_.jNullReference; + _writeToParcel(reference.pointer, _id_writeToParcel as jni$_.JMethodIDPtr, + _$parcel.pointer, i) + .check(); + } +} + +final class $Bitmap$NullableType extends jni$_.JObjType { + @jni$_.internal + const $Bitmap$NullableType(); + + @jni$_.internal + @core$_.override + String get signature => r'Landroid/graphics/Bitmap;'; @jni$_.internal @core$_.override @@ -42260,6 +42339,17 @@ class Context extends jni$_.JObject { static jni$_.JString? get ACTIVITY_SERVICE => _id_ACTIVITY_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_ADVANCED_PROTECTION_SERVICE = _class.staticFieldId( + r'ADVANCED_PROTECTION_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String ADVANCED_PROTECTION_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get ADVANCED_PROTECTION_SERVICE => + _id_ADVANCED_PROTECTION_SERVICE.get( + _class, const jni$_.JStringNullableType()); + static final _id_ALARM_SERVICE = _class.staticFieldId( r'ALARM_SERVICE', r'Ljava/lang/String;', @@ -42280,6 +42370,16 @@ class Context extends jni$_.JObject { static jni$_.JString? get APPWIDGET_SERVICE => _id_APPWIDGET_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_APP_FUNCTION_SERVICE = _class.staticFieldId( + r'APP_FUNCTION_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String APP_FUNCTION_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get APP_FUNCTION_SERVICE => + _id_APP_FUNCTION_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_APP_OPS_SERVICE = _class.staticFieldId( r'APP_OPS_SERVICE', r'Ljava/lang/String;', @@ -42723,6 +42823,16 @@ class Context extends jni$_.JObject { static jni$_.JString? get KEYGUARD_SERVICE => _id_KEYGUARD_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_KEYSTORE_SERVICE = _class.staticFieldId( + r'KEYSTORE_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String KEYSTORE_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get KEYSTORE_SERVICE => + _id_KEYSTORE_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_LAUNCHER_APPS_SERVICE = _class.staticFieldId( r'LAUNCHER_APPS_SERVICE', r'Ljava/lang/String;', @@ -42796,6 +42906,16 @@ class Context extends jni$_.JObject { _id_MEDIA_PROJECTION_SERVICE.get( _class, const jni$_.JStringNullableType()); + static final _id_MEDIA_QUALITY_SERVICE = _class.staticFieldId( + r'MEDIA_QUALITY_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String MEDIA_QUALITY_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get MEDIA_QUALITY_SERVICE => + _id_MEDIA_QUALITY_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_MEDIA_ROUTER_SERVICE = _class.staticFieldId( r'MEDIA_ROUTER_SERVICE', r'Ljava/lang/String;', @@ -42986,6 +43106,16 @@ class Context extends jni$_.JObject { static jni$_.JString? get ROLE_SERVICE => _id_ROLE_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_SATELLITE_SERVICE = _class.staticFieldId( + r'SATELLITE_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String SATELLITE_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get SATELLITE_SERVICE => + _id_SATELLITE_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_SEARCH_SERVICE = _class.staticFieldId( r'SEARCH_SERVICE', r'Ljava/lang/String;', @@ -43107,6 +43237,16 @@ class Context extends jni$_.JObject { _id_TELEPHONY_SUBSCRIPTION_SERVICE.get( _class, const jni$_.JStringNullableType()); + static final _id_TETHERING_SERVICE = _class.staticFieldId( + r'TETHERING_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String TETHERING_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get TETHERING_SERVICE => + _id_TETHERING_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_TEXT_CLASSIFICATION_SERVICE = _class.staticFieldId( r'TEXT_CLASSIFICATION_SERVICE', r'Ljava/lang/String;', @@ -43129,6 +43269,16 @@ class Context extends jni$_.JObject { _id_TEXT_SERVICES_MANAGER_SERVICE.get( _class, const jni$_.JStringNullableType()); + static final _id_TV_AD_SERVICE = _class.staticFieldId( + r'TV_AD_SERVICE', + r'Ljava/lang/String;', + ); + + /// from: `static public final java.lang.String TV_AD_SERVICE` + /// The returned object must be released after use, by calling the [release] method. + static jni$_.JString? get TV_AD_SERVICE => + _id_TV_AD_SERVICE.get(_class, const jni$_.JStringNullableType()); + static final _id_TV_INPUT_SERVICE = _class.staticFieldId( r'TV_INPUT_SERVICE', r'Ljava/lang/String;', @@ -43292,501 +43442,728 @@ class Context extends jni$_.JObject { static jni$_.JString? get WINDOW_SERVICE => _id_WINDOW_SERVICE.get(_class, const jni$_.JStringNullableType()); - static final _id_getAssets = _class.instanceMethodId( - r'getAssets', - r'()Landroid/content/res/AssetManager;', + static final _id_bindIsolatedService = _class.instanceMethodId( + r'bindIsolatedService', + r'(Landroid/content/Intent;Landroid/content/Context$BindServiceFlags;Ljava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', ); - static final _getAssets = jni$_.ProtectedJniExtensions.lookup< + static final _bindIsolatedService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract android.content.res.AssetManager getAssets()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getAssets() { - return _getAssets(reference.pointer, _id_getAssets as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean bindIsolatedService(android.content.Intent intent, android.content.Context$BindServiceFlags bindServiceFlags, java.lang.String string, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` + bool bindIsolatedService( + jni$_.JObject? intent, + Context$BindServiceFlags? bindServiceFlags, + jni$_.JString? string, + jni$_.JObject? executor, + jni$_.JObject? serviceConnection, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$bindServiceFlags = + bindServiceFlags?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$executor = executor?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + return _bindIsolatedService( + reference.pointer, + _id_bindIsolatedService as jni$_.JMethodIDPtr, + _$intent.pointer, + _$bindServiceFlags.pointer, + _$string.pointer, + _$executor.pointer, + _$serviceConnection.pointer) + .boolean; } - static final _id_getResources = _class.instanceMethodId( - r'getResources', - r'()Landroid/content/res/Resources;', + static final _id_bindIsolatedService$1 = _class.instanceMethodId( + r'bindIsolatedService', + r'(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', ); - static final _getResources = jni$_.ProtectedJniExtensions.lookup< + static final _bindIsolatedService$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract android.content.res.Resources getResources()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getResources() { - return _getResources( - reference.pointer, _id_getResources as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean bindIsolatedService(android.content.Intent intent, int i, java.lang.String string, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` + bool bindIsolatedService$1( + jni$_.JObject? intent, + int i, + jni$_.JString? string, + jni$_.JObject? executor, + jni$_.JObject? serviceConnection, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$executor = executor?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + return _bindIsolatedService$1( + reference.pointer, + _id_bindIsolatedService$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + i, + _$string.pointer, + _$executor.pointer, + _$serviceConnection.pointer) + .boolean; } - static final _id_getPackageManager = _class.instanceMethodId( - r'getPackageManager', - r'()Landroid/content/pm/PackageManager;', + static final _id_bindService = _class.instanceMethodId( + r'bindService', + r'(Landroid/content/Intent;Landroid/content/Context$BindServiceFlags;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', ); - static final _getPackageManager = jni$_.ProtectedJniExtensions.lookup< + static final _bindService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract android.content.pm.PackageManager getPackageManager()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getPackageManager() { - return _getPackageManager( - reference.pointer, _id_getPackageManager as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean bindService(android.content.Intent intent, android.content.Context$BindServiceFlags bindServiceFlags, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` + bool bindService( + jni$_.JObject? intent, + Context$BindServiceFlags? bindServiceFlags, + jni$_.JObject? executor, + jni$_.JObject? serviceConnection, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$bindServiceFlags = + bindServiceFlags?.reference ?? jni$_.jNullReference; + final _$executor = executor?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + return _bindService( + reference.pointer, + _id_bindService as jni$_.JMethodIDPtr, + _$intent.pointer, + _$bindServiceFlags.pointer, + _$executor.pointer, + _$serviceConnection.pointer) + .boolean; } - static final _id_getContentResolver = _class.instanceMethodId( - r'getContentResolver', - r'()Landroid/content/ContentResolver;', + static final _id_bindService$1 = _class.instanceMethodId( + r'bindService', + r'(Landroid/content/Intent;Landroid/content/ServiceConnection;Landroid/content/Context$BindServiceFlags;)Z', ); - static final _getContentResolver = jni$_.ProtectedJniExtensions.lookup< + static final _bindService$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract android.content.ContentResolver getContentResolver()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getContentResolver() { - return _getContentResolver( - reference.pointer, _id_getContentResolver as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean bindService(android.content.Intent intent, android.content.ServiceConnection serviceConnection, android.content.Context$BindServiceFlags bindServiceFlags)` + bool bindService$1( + jni$_.JObject? intent, + jni$_.JObject? serviceConnection, + Context$BindServiceFlags? bindServiceFlags, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + final _$bindServiceFlags = + bindServiceFlags?.reference ?? jni$_.jNullReference; + return _bindService$1( + reference.pointer, + _id_bindService$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$serviceConnection.pointer, + _$bindServiceFlags.pointer) + .boolean; } - static final _id_getMainLooper = _class.instanceMethodId( - r'getMainLooper', - r'()Landroid/os/Looper;', + static final _id_bindService$2 = _class.instanceMethodId( + r'bindService', + r'(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z', ); - static final _getMainLooper = jni$_.ProtectedJniExtensions.lookup< + static final _bindService$2 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32 + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + int)>(); - /// from: `public abstract android.os.Looper getMainLooper()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getMainLooper() { - return _getMainLooper( - reference.pointer, _id_getMainLooper as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public abstract boolean bindService(android.content.Intent intent, android.content.ServiceConnection serviceConnection, int i)` + bool bindService$2( + jni$_.JObject? intent, + jni$_.JObject? serviceConnection, + int i, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + return _bindService$2( + reference.pointer, + _id_bindService$2 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$serviceConnection.pointer, + i) + .boolean; } - static final _id_getMainExecutor = _class.instanceMethodId( - r'getMainExecutor', - r'()Ljava/util/concurrent/Executor;', + static final _id_bindService$3 = _class.instanceMethodId( + r'bindService', + r'(Landroid/content/Intent;ILjava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', ); - static final _getMainExecutor = jni$_.ProtectedJniExtensions.lookup< + static final _bindService$3 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public java.util.concurrent.Executor getMainExecutor()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getMainExecutor() { - return _getMainExecutor( - reference.pointer, _id_getMainExecutor as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public boolean bindService(android.content.Intent intent, int i, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` + bool bindService$3( + jni$_.JObject? intent, + int i, + jni$_.JObject? executor, + jni$_.JObject? serviceConnection, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$executor = executor?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + return _bindService$3( + reference.pointer, + _id_bindService$3 as jni$_.JMethodIDPtr, + _$intent.pointer, + i, + _$executor.pointer, + _$serviceConnection.pointer) + .boolean; } - static final _id_getApplicationContext = _class.instanceMethodId( - r'getApplicationContext', - r'()Landroid/content/Context;', + static final _id_bindServiceAsUser = _class.instanceMethodId( + r'bindServiceAsUser', + r'(Landroid/content/Intent;Landroid/content/ServiceConnection;Landroid/content/Context$BindServiceFlags;Landroid/os/UserHandle;)Z', ); - static final _getApplicationContext = jni$_.ProtectedJniExtensions.lookup< + static final _bindServiceAsUser = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract android.content.Context getApplicationContext()` - /// The returned object must be released after use, by calling the [release] method. - Context? getApplicationContext() { - return _getApplicationContext( - reference.pointer, _id_getApplicationContext as jni$_.JMethodIDPtr) - .object(const $Context$NullableType()); + /// from: `public boolean bindServiceAsUser(android.content.Intent intent, android.content.ServiceConnection serviceConnection, android.content.Context$BindServiceFlags bindServiceFlags, android.os.UserHandle userHandle)` + bool bindServiceAsUser( + jni$_.JObject? intent, + jni$_.JObject? serviceConnection, + Context$BindServiceFlags? bindServiceFlags, + jni$_.JObject? userHandle, + ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + final _$bindServiceFlags = + bindServiceFlags?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + return _bindServiceAsUser( + reference.pointer, + _id_bindServiceAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$serviceConnection.pointer, + _$bindServiceFlags.pointer, + _$userHandle.pointer) + .boolean; } - static final _id_registerComponentCallbacks = _class.instanceMethodId( - r'registerComponentCallbacks', - r'(Landroid/content/ComponentCallbacks;)V', + static final _id_bindServiceAsUser$1 = _class.instanceMethodId( + r'bindServiceAsUser', + r'(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/UserHandle;)Z', ); - static final _registerComponentCallbacks = - 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)>(); + static final _bindServiceAsUser$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + int, + jni$_.Pointer)>(); - /// from: `public void registerComponentCallbacks(android.content.ComponentCallbacks componentCallbacks)` - void registerComponentCallbacks( - jni$_.JObject? componentCallbacks, + /// from: `public boolean bindServiceAsUser(android.content.Intent intent, android.content.ServiceConnection serviceConnection, int i, android.os.UserHandle userHandle)` + bool bindServiceAsUser$1( + jni$_.JObject? intent, + jni$_.JObject? serviceConnection, + int i, + jni$_.JObject? userHandle, ) { - final _$componentCallbacks = - componentCallbacks?.reference ?? jni$_.jNullReference; - _registerComponentCallbacks( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + return _bindServiceAsUser$1( reference.pointer, - _id_registerComponentCallbacks as jni$_.JMethodIDPtr, - _$componentCallbacks.pointer) - .check(); + _id_bindServiceAsUser$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$serviceConnection.pointer, + i, + _$userHandle.pointer) + .boolean; } - static final _id_unregisterComponentCallbacks = _class.instanceMethodId( - r'unregisterComponentCallbacks', - r'(Landroid/content/ComponentCallbacks;)V', + static final _id_checkCallingOrSelfPermission = _class.instanceMethodId( + r'checkCallingOrSelfPermission', + r'(Ljava/lang/String;)I', ); - static final _unregisterComponentCallbacks = + static final _checkCallingOrSelfPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + 'globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void unregisterComponentCallbacks(android.content.ComponentCallbacks componentCallbacks)` - void unregisterComponentCallbacks( - jni$_.JObject? componentCallbacks, + /// from: `public abstract int checkCallingOrSelfPermission(java.lang.String string)` + int checkCallingOrSelfPermission( + jni$_.JString? string, ) { - final _$componentCallbacks = - componentCallbacks?.reference ?? jni$_.jNullReference; - _unregisterComponentCallbacks( + final _$string = string?.reference ?? jni$_.jNullReference; + return _checkCallingOrSelfPermission( reference.pointer, - _id_unregisterComponentCallbacks as jni$_.JMethodIDPtr, - _$componentCallbacks.pointer) - .check(); + _id_checkCallingOrSelfPermission as jni$_.JMethodIDPtr, + _$string.pointer) + .integer; } - static final _id_getText = _class.instanceMethodId( - r'getText', - r'(I)Ljava/lang/CharSequence;', + static final _id_checkCallingOrSelfUriPermission = _class.instanceMethodId( + r'checkCallingOrSelfUriPermission', + r'(Landroid/net/Uri;I)I', ); - static final _getText = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - - /// from: `public final java.lang.CharSequence getText(int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getText( - int i, - ) { - return _getText(reference.pointer, _id_getText as jni$_.JMethodIDPtr, i) - .object(const jni$_.JObjectNullableType()); + static final _checkCallingOrSelfUriPermission = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32 + )>)>>('globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + + /// from: `public abstract int checkCallingOrSelfUriPermission(android.net.Uri uri, int i)` + int checkCallingOrSelfUriPermission( + jni$_.JObject? uri, + int i, + ) { + final _$uri = uri?.reference ?? jni$_.jNullReference; + return _checkCallingOrSelfUriPermission( + reference.pointer, + _id_checkCallingOrSelfUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, + i) + .integer; } - static final _id_getString = _class.instanceMethodId( - r'getString', - r'(I)Ljava/lang/String;', + static final _id_checkCallingOrSelfUriPermissions = _class.instanceMethodId( + r'checkCallingOrSelfUriPermissions', + r'(Ljava/util/List;I)[I', ); - static final _getString = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + static final _checkCallingOrSelfUriPermissions = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32 + )>)>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public final java.lang.String getString(int i)` + /// from: `public int[] checkCallingOrSelfUriPermissions(java.util.List list, int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getString( + jni$_.JIntArray? checkCallingOrSelfUriPermissions( + jni$_.JList? list, int i, ) { - return _getString(reference.pointer, _id_getString as jni$_.JMethodIDPtr, i) - .object(const jni$_.JStringNullableType()); + final _$list = list?.reference ?? jni$_.jNullReference; + return _checkCallingOrSelfUriPermissions( + reference.pointer, + _id_checkCallingOrSelfUriPermissions as jni$_.JMethodIDPtr, + _$list.pointer, + i) + .object(const jni$_.JIntArrayNullableType()); } - static final _id_getString$1 = _class.instanceMethodId( - r'getString', - r'(I[Ljava/lang/Object;)Ljava/lang/String;', + static final _id_checkCallingPermission = _class.instanceMethodId( + r'checkCallingPermission', + r'(Ljava/lang/String;)I', ); - static final _getString$1 = jni$_.ProtectedJniExtensions.lookup< + static final _checkCallingPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( - 'globalEnv_CallObjectMethod') + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public final java.lang.String getString(int i, java.lang.Object[] objects)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getString$1( - int i, - jni$_.JArray? objects, + /// from: `public abstract int checkCallingPermission(java.lang.String string)` + int checkCallingPermission( + jni$_.JString? string, ) { - final _$objects = objects?.reference ?? jni$_.jNullReference; - return _getString$1(reference.pointer, - _id_getString$1 as jni$_.JMethodIDPtr, i, _$objects.pointer) - .object(const jni$_.JStringNullableType()); + final _$string = string?.reference ?? jni$_.jNullReference; + return _checkCallingPermission(reference.pointer, + _id_checkCallingPermission as jni$_.JMethodIDPtr, _$string.pointer) + .integer; } - static final _id_getColor = _class.instanceMethodId( - r'getColor', - r'(I)I', + static final _id_checkCallingUriPermission = _class.instanceMethodId( + r'checkCallingUriPermission', + r'(Landroid/net/Uri;I)I', ); - static final _getColor = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') + static final _checkCallingUriPermission = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallIntMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public final int getColor(int i)` - int getColor( + /// from: `public abstract int checkCallingUriPermission(android.net.Uri uri, int i)` + int checkCallingUriPermission( + jni$_.JObject? uri, int i, ) { - return _getColor(reference.pointer, _id_getColor as jni$_.JMethodIDPtr, i) + final _$uri = uri?.reference ?? jni$_.jNullReference; + return _checkCallingUriPermission( + reference.pointer, + _id_checkCallingUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, + i) .integer; } - static final _id_getDrawable = _class.instanceMethodId( - r'getDrawable', - r'(I)Landroid/graphics/drawable/Drawable;', + static final _id_checkCallingUriPermissions = _class.instanceMethodId( + r'checkCallingUriPermissions', + r'(Ljava/util/List;I)[I', ); - static final _getDrawable = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + static final _checkCallingUriPermissions = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32 + )>)>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public final android.graphics.drawable.Drawable getDrawable(int i)` + /// from: `public int[] checkCallingUriPermissions(java.util.List list, int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getDrawable( + jni$_.JIntArray? checkCallingUriPermissions( + jni$_.JList? list, int i, ) { - return _getDrawable( - reference.pointer, _id_getDrawable as jni$_.JMethodIDPtr, i) - .object(const jni$_.JObjectNullableType()); + final _$list = list?.reference ?? jni$_.jNullReference; + return _checkCallingUriPermissions( + reference.pointer, + _id_checkCallingUriPermissions as jni$_.JMethodIDPtr, + _$list.pointer, + i) + .object(const jni$_.JIntArrayNullableType()); } - static final _id_getColorStateList = _class.instanceMethodId( - r'getColorStateList', - r'(I)Landroid/content/res/ColorStateList;', + static final _id_checkContentUriPermissionFull = _class.instanceMethodId( + r'checkContentUriPermissionFull', + r'(Landroid/net/Uri;III)I', ); - static final _getColorStateList = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< + static final _checkContentUriPermissionFull = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallIntMethod') + .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.Pointer, + int, + int, + int)>(); - /// from: `public final android.content.res.ColorStateList getColorStateList(int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getColorStateList( + /// from: `public int checkContentUriPermissionFull(android.net.Uri uri, int i, int i1, int i2)` + int checkContentUriPermissionFull( + jni$_.JObject? uri, int i, + int i1, + int i2, ) { - return _getColorStateList( - reference.pointer, _id_getColorStateList as jni$_.JMethodIDPtr, i) - .object(const jni$_.JObjectNullableType()); + final _$uri = uri?.reference ?? jni$_.jNullReference; + return _checkContentUriPermissionFull( + reference.pointer, + _id_checkContentUriPermissionFull as jni$_.JMethodIDPtr, + _$uri.pointer, + i, + i1, + i2) + .integer; } - static final _id_setTheme = _class.instanceMethodId( - r'setTheme', - r'(I)V', + static final _id_checkPermission = _class.instanceMethodId( + r'checkPermission', + r'(Ljava/lang/String;II)I', ); - static final _setTheme = jni$_.ProtectedJniExtensions.lookup< + static final _checkPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int, int)>(); - /// from: `public abstract void setTheme(int i)` - void setTheme( + /// from: `public abstract int checkPermission(java.lang.String string, int i, int i1)` + int checkPermission( + jni$_.JString? string, int i, + int i1, ) { - _setTheme(reference.pointer, _id_setTheme as jni$_.JMethodIDPtr, i).check(); - } - - static final _id_getTheme = _class.instanceMethodId( - r'getTheme', - r'()Landroid/content/res/Resources$Theme;', - ); - - static final _getTheme = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public abstract android.content.res.Resources$Theme getTheme()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getTheme() { - return _getTheme(reference.pointer, _id_getTheme as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + final _$string = string?.reference ?? jni$_.jNullReference; + return _checkPermission(reference.pointer, + _id_checkPermission as jni$_.JMethodIDPtr, _$string.pointer, i, i1) + .integer; } - static final _id_obtainStyledAttributes = _class.instanceMethodId( - r'obtainStyledAttributes', - r'([I)Landroid/content/res/TypedArray;', + static final _id_checkSelfPermission = _class.instanceMethodId( + r'checkSelfPermission', + r'(Ljava/lang/String;)I', ); - static final _obtainStyledAttributes = jni$_.ProtectedJniExtensions.lookup< + static final _checkSelfPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + 'globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public final android.content.res.TypedArray obtainStyledAttributes(int[] is)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? obtainStyledAttributes( - jni$_.JIntArray? is$, + /// from: `public abstract int checkSelfPermission(java.lang.String string)` + int checkSelfPermission( + jni$_.JString? string, ) { - final _$is$ = is$?.reference ?? jni$_.jNullReference; - return _obtainStyledAttributes(reference.pointer, - _id_obtainStyledAttributes as jni$_.JMethodIDPtr, _$is$.pointer) - .object(const jni$_.JObjectNullableType()); + final _$string = string?.reference ?? jni$_.jNullReference; + return _checkSelfPermission(reference.pointer, + _id_checkSelfPermission as jni$_.JMethodIDPtr, _$string.pointer) + .integer; } - static final _id_obtainStyledAttributes$1 = _class.instanceMethodId( - r'obtainStyledAttributes', - r'(I[I)Landroid/content/res/TypedArray;', + static final _id_checkUriPermission = _class.instanceMethodId( + r'checkUriPermission', + r'(Landroid/net/Uri;III)I', ); - static final _obtainStyledAttributes$1 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( - 'globalEnv_CallObjectMethod') + static final _checkUriPermission = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); + jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); - /// from: `public final android.content.res.TypedArray obtainStyledAttributes(int i, int[] is)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? obtainStyledAttributes$1( + /// from: `public abstract int checkUriPermission(android.net.Uri uri, int i, int i1, int i2)` + int checkUriPermission( + jni$_.JObject? uri, int i, - jni$_.JIntArray? is$, + int i1, + int i2, ) { - final _$is$ = is$?.reference ?? jni$_.jNullReference; - return _obtainStyledAttributes$1( + final _$uri = uri?.reference ?? jni$_.jNullReference; + return _checkUriPermission( reference.pointer, - _id_obtainStyledAttributes$1 as jni$_.JMethodIDPtr, + _id_checkUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, i, - _$is$.pointer) - .object(const jni$_.JObjectNullableType()); + i1, + i2) + .integer; } - static final _id_obtainStyledAttributes$2 = _class.instanceMethodId( - r'obtainStyledAttributes', - r'(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;', + static final _id_checkUriPermission$1 = _class.instanceMethodId( + r'checkUriPermission', + r'(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;III)I', ); - static final _obtainStyledAttributes$2 = jni$_.ProtectedJniExtensions.lookup< + static final _checkUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -43794,307 +44171,308 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.Pointer, + int, + int, + int)>(); - /// from: `public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet attributeSet, int[] is)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? obtainStyledAttributes$2( - jni$_.JObject? attributeSet, - jni$_.JIntArray? is$, + /// from: `public abstract int checkUriPermission(android.net.Uri uri, java.lang.String string, java.lang.String string1, int i, int i1, int i2)` + int checkUriPermission$1( + jni$_.JObject? uri, + jni$_.JString? string, + jni$_.JString? string1, + int i, + int i1, + int i2, ) { - final _$attributeSet = attributeSet?.reference ?? jni$_.jNullReference; - final _$is$ = is$?.reference ?? jni$_.jNullReference; - return _obtainStyledAttributes$2( + final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + return _checkUriPermission$1( reference.pointer, - _id_obtainStyledAttributes$2 as jni$_.JMethodIDPtr, - _$attributeSet.pointer, - _$is$.pointer) - .object(const jni$_.JObjectNullableType()); + _id_checkUriPermission$1 as jni$_.JMethodIDPtr, + _$uri.pointer, + _$string.pointer, + _$string1.pointer, + i, + i1, + i2) + .integer; } - static final _id_obtainStyledAttributes$3 = _class.instanceMethodId( - r'obtainStyledAttributes', - r'(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;', + static final _id_checkUriPermissions = _class.instanceMethodId( + r'checkUriPermissions', + r'(Ljava/util/List;III)[I', ); - static final _obtainStyledAttributes$3 = jni$_.ProtectedJniExtensions.lookup< + static final _checkUriPermissions = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, jni$_.Pointer, jni$_.Int32, + jni$_.Int32, jni$_.Int32 )>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - int, - int)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); - /// from: `public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet attributeSet, int[] is, int i, int i1)` + /// from: `public int[] checkUriPermissions(java.util.List list, int i, int i1, int i2)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? obtainStyledAttributes$3( - jni$_.JObject? attributeSet, - jni$_.JIntArray? is$, + jni$_.JIntArray? checkUriPermissions( + jni$_.JList? list, int i, int i1, + int i2, ) { - final _$attributeSet = attributeSet?.reference ?? jni$_.jNullReference; - final _$is$ = is$?.reference ?? jni$_.jNullReference; - return _obtainStyledAttributes$3( + final _$list = list?.reference ?? jni$_.jNullReference; + return _checkUriPermissions( reference.pointer, - _id_obtainStyledAttributes$3 as jni$_.JMethodIDPtr, - _$attributeSet.pointer, - _$is$.pointer, + _id_checkUriPermissions as jni$_.JMethodIDPtr, + _$list.pointer, i, - i1) - .object(const jni$_.JObjectNullableType()); + i1, + i2) + .object(const jni$_.JIntArrayNullableType()); } - static final _id_getClassLoader = _class.instanceMethodId( - r'getClassLoader', - r'()Ljava/lang/ClassLoader;', + static final _id_clearWallpaper = _class.instanceMethodId( + r'clearWallpaper', + r'()V', ); - static final _getClassLoader = jni$_.ProtectedJniExtensions.lookup< + static final _clearWallpaper = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + )>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.lang.ClassLoader getClassLoader()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getClassLoader() { - return _getClassLoader( - reference.pointer, _id_getClassLoader as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public abstract void clearWallpaper()` + void clearWallpaper() { + _clearWallpaper(reference.pointer, _id_clearWallpaper as jni$_.JMethodIDPtr) + .check(); } - static final _id_getPackageName = _class.instanceMethodId( - r'getPackageName', - r'()Ljava/lang/String;', + static final _id_createAttributionContext = _class.instanceMethodId( + r'createAttributionContext', + r'(Ljava/lang/String;)Landroid/content/Context;', ); - static final _getPackageName = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + static final _createAttributionContext = 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$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract java.lang.String getPackageName()` + /// from: `public android.content.Context createAttributionContext(java.lang.String string)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getPackageName() { - return _getPackageName( - reference.pointer, _id_getPackageName as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); - } - - static final _id_getOpPackageName = _class.instanceMethodId( - r'getOpPackageName', - r'()Ljava/lang/String;', - ); - - static final _getOpPackageName = 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 getOpPackageName()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getOpPackageName() { - return _getOpPackageName( - reference.pointer, _id_getOpPackageName as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); + Context? createAttributionContext( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return _createAttributionContext( + reference.pointer, + _id_createAttributionContext as jni$_.JMethodIDPtr, + _$string.pointer) + .object(const $Context$NullableType()); } - static final _id_getAttributionTag = _class.instanceMethodId( - r'getAttributionTag', - r'()Ljava/lang/String;', + static final _id_createConfigurationContext = _class.instanceMethodId( + r'createConfigurationContext', + r'(Landroid/content/res/Configuration;)Landroid/content/Context;', ); - static final _getAttributionTag = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + static final _createConfigurationContext = + 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 java.lang.String getAttributionTag()` + /// from: `public abstract android.content.Context createConfigurationContext(android.content.res.Configuration configuration)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getAttributionTag() { - return _getAttributionTag( - reference.pointer, _id_getAttributionTag as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); + Context? createConfigurationContext( + jni$_.JObject? configuration, + ) { + final _$configuration = configuration?.reference ?? jni$_.jNullReference; + return _createConfigurationContext( + reference.pointer, + _id_createConfigurationContext as jni$_.JMethodIDPtr, + _$configuration.pointer) + .object(const $Context$NullableType()); } - static final _id_getAttributionSource = _class.instanceMethodId( - r'getAttributionSource', - r'()Landroid/content/AttributionSource;', + static final _id_createContext = _class.instanceMethodId( + r'createContext', + r'(Landroid/content/ContextParams;)Landroid/content/Context;', ); - static final _getAttributionSource = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + static final _createContext = 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$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public android.content.AttributionSource getAttributionSource()` + /// from: `public android.content.Context createContext(android.content.ContextParams contextParams)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getAttributionSource() { - return _getAttributionSource( - reference.pointer, _id_getAttributionSource as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + Context? createContext( + jni$_.JObject? contextParams, + ) { + final _$contextParams = contextParams?.reference ?? jni$_.jNullReference; + return _createContext(reference.pointer, + _id_createContext as jni$_.JMethodIDPtr, _$contextParams.pointer) + .object(const $Context$NullableType()); } - static final _id_getParams = _class.instanceMethodId( - r'getParams', - r'()Landroid/content/ContextParams;', + static final _id_createContextForSplit = _class.instanceMethodId( + r'createContextForSplit', + r'(Ljava/lang/String;)Landroid/content/Context;', ); - static final _getParams = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + static final _createContextForSplit = 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$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public android.content.ContextParams getParams()` + /// from: `public abstract android.content.Context createContextForSplit(java.lang.String string)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getParams() { - return _getParams(reference.pointer, _id_getParams as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + Context? createContextForSplit( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return _createContextForSplit(reference.pointer, + _id_createContextForSplit as jni$_.JMethodIDPtr, _$string.pointer) + .object(const $Context$NullableType()); } - static final _id_getApplicationInfo = _class.instanceMethodId( - r'getApplicationInfo', - r'()Landroid/content/pm/ApplicationInfo;', + static final _id_createDeviceContext = _class.instanceMethodId( + r'createDeviceContext', + r'(I)Landroid/content/Context;', ); - static final _getApplicationInfo = jni$_.ProtectedJniExtensions.lookup< + static final _createDeviceContext = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract android.content.pm.ApplicationInfo getApplicationInfo()` + /// from: `public android.content.Context createDeviceContext(int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getApplicationInfo() { - return _getApplicationInfo( - reference.pointer, _id_getApplicationInfo as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + Context? createDeviceContext( + int i, + ) { + return _createDeviceContext( + reference.pointer, _id_createDeviceContext as jni$_.JMethodIDPtr, i) + .object(const $Context$NullableType()); } - static final _id_getPackageResourcePath = _class.instanceMethodId( - r'getPackageResourcePath', - r'()Ljava/lang/String;', + static final _id_createDeviceProtectedStorageContext = + _class.instanceMethodId( + r'createDeviceProtectedStorageContext', + r'()Landroid/content/Context;', ); - static final _getPackageResourcePath = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< + static final _createDeviceProtectedStorageContext = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + )>(); - /// from: `public abstract java.lang.String getPackageResourcePath()` + /// from: `public abstract android.content.Context createDeviceProtectedStorageContext()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getPackageResourcePath() { - return _getPackageResourcePath( - reference.pointer, _id_getPackageResourcePath as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); + Context? createDeviceProtectedStorageContext() { + return _createDeviceProtectedStorageContext(reference.pointer, + _id_createDeviceProtectedStorageContext as jni$_.JMethodIDPtr) + .object(const $Context$NullableType()); } - static final _id_getPackageCodePath = _class.instanceMethodId( - r'getPackageCodePath', - r'()Ljava/lang/String;', + static final _id_createDisplayContext = _class.instanceMethodId( + r'createDisplayContext', + r'(Landroid/view/Display;)Landroid/content/Context;', ); - static final _getPackageCodePath = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + static final _createDisplayContext = 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$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract java.lang.String getPackageCodePath()` + /// from: `public abstract android.content.Context createDisplayContext(android.view.Display display)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getPackageCodePath() { - return _getPackageCodePath( - reference.pointer, _id_getPackageCodePath as jni$_.JMethodIDPtr) - .object(const jni$_.JStringNullableType()); + Context? createDisplayContext( + jni$_.JObject? display, + ) { + final _$display = display?.reference ?? jni$_.jNullReference; + return _createDisplayContext(reference.pointer, + _id_createDisplayContext as jni$_.JMethodIDPtr, _$display.pointer) + .object(const $Context$NullableType()); } - static final _id_getSharedPreferences = _class.instanceMethodId( - r'getSharedPreferences', - r'(Ljava/lang/String;I)Landroid/content/SharedPreferences;', + static final _id_createPackageContext = _class.instanceMethodId( + r'createPackageContext', + r'(Ljava/lang/String;I)Landroid/content/Context;', ); - static final _getSharedPreferences = jni$_.ProtectedJniExtensions.lookup< + static final _createPackageContext = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44106,24 +44484,24 @@ class Context extends jni$_.JObject { jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String string, int i)` + /// from: `public abstract android.content.Context createPackageContext(java.lang.String string, int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getSharedPreferences( + Context? createPackageContext( jni$_.JString? string, int i, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _getSharedPreferences(reference.pointer, - _id_getSharedPreferences as jni$_.JMethodIDPtr, _$string.pointer, i) - .object(const jni$_.JObjectNullableType()); + return _createPackageContext(reference.pointer, + _id_createPackageContext as jni$_.JMethodIDPtr, _$string.pointer, i) + .object(const $Context$NullableType()); } - static final _id_moveSharedPreferencesFrom = _class.instanceMethodId( - r'moveSharedPreferencesFrom', - r'(Landroid/content/Context;Ljava/lang/String;)Z', + static final _id_createWindowContext = _class.instanceMethodId( + r'createWindowContext', + r'(Landroid/view/Display;ILandroid/os/Bundle;)Landroid/content/Context;', ); - static final _moveSharedPreferencesFrom = jni$_.ProtectedJniExtensions.lookup< + static final _createWindowContext = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44131,110 +44509,118 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, + jni$_.Int32, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + int, jni$_.Pointer)>(); - /// from: `public abstract boolean moveSharedPreferencesFrom(android.content.Context context, java.lang.String string)` - bool moveSharedPreferencesFrom( - Context? context, - jni$_.JString? string, + /// from: `public android.content.Context createWindowContext(android.view.Display display, int i, android.os.Bundle bundle)` + /// The returned object must be released after use, by calling the [release] method. + Context? createWindowContext( + jni$_.JObject? display, + int i, + jni$_.JObject? bundle, ) { - final _$context = context?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - return _moveSharedPreferencesFrom( + final _$display = display?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + return _createWindowContext( reference.pointer, - _id_moveSharedPreferencesFrom as jni$_.JMethodIDPtr, - _$context.pointer, - _$string.pointer) - .boolean; + _id_createWindowContext as jni$_.JMethodIDPtr, + _$display.pointer, + i, + _$bundle.pointer) + .object(const $Context$NullableType()); } - static final _id_deleteSharedPreferences = _class.instanceMethodId( - r'deleteSharedPreferences', - r'(Ljava/lang/String;)Z', + static final _id_createWindowContext$1 = _class.instanceMethodId( + r'createWindowContext', + r'(ILandroid/os/Bundle;)Landroid/content/Context;', ); - static final _deleteSharedPreferences = jni$_.ProtectedJniExtensions.lookup< + static final _createWindowContext$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallBooleanMethod') + jni$_ + .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); - /// from: `public abstract boolean deleteSharedPreferences(java.lang.String string)` - bool deleteSharedPreferences( - jni$_.JString? string, + /// from: `public android.content.Context createWindowContext(int i, android.os.Bundle bundle)` + /// The returned object must be released after use, by calling the [release] method. + Context? createWindowContext$1( + int i, + jni$_.JObject? bundle, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _deleteSharedPreferences(reference.pointer, - _id_deleteSharedPreferences as jni$_.JMethodIDPtr, _$string.pointer) - .boolean; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + return _createWindowContext$1( + reference.pointer, + _id_createWindowContext$1 as jni$_.JMethodIDPtr, + i, + _$bundle.pointer) + .object(const $Context$NullableType()); } - static final _id_openFileInput = _class.instanceMethodId( - r'openFileInput', - r'(Ljava/lang/String;)Ljava/io/FileInputStream;', + static final _id_databaseList = _class.instanceMethodId( + r'databaseList', + r'()[Ljava/lang/String;', ); - static final _openFileInput = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + static final _databaseList = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract java.io.FileInputStream openFileInput(java.lang.String string)` + /// from: `public abstract java.lang.String[] databaseList()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? openFileInput( - jni$_.JString? string, - ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _openFileInput(reference.pointer, - _id_openFileInput as jni$_.JMethodIDPtr, _$string.pointer) - .object(const jni$_.JObjectNullableType()); + jni$_.JArray? databaseList() { + return _databaseList( + reference.pointer, _id_databaseList as jni$_.JMethodIDPtr) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JStringNullableType())); } - static final _id_openFileOutput = _class.instanceMethodId( - r'openFileOutput', - r'(Ljava/lang/String;I)Ljava/io/FileOutputStream;', + static final _id_deleteDatabase = _class.instanceMethodId( + r'deleteDatabase', + r'(Ljava/lang/String;)Z', ); - static final _openFileOutput = jni$_.ProtectedJniExtensions.lookup< + static final _deleteDatabase = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallObjectMethod') + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract java.io.FileOutputStream openFileOutput(java.lang.String string, int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? openFileOutput( + /// from: `public abstract boolean deleteDatabase(java.lang.String string)` + bool deleteDatabase( jni$_.JString? string, - int i, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _openFileOutput(reference.pointer, - _id_openFileOutput as jni$_.JMethodIDPtr, _$string.pointer, i) - .object(const jni$_.JObjectNullableType()); + return _deleteDatabase(reference.pointer, + _id_deleteDatabase as jni$_.JMethodIDPtr, _$string.pointer) + .boolean; } static final _id_deleteFile = _class.instanceMethodId( @@ -44263,169 +44649,350 @@ class Context extends jni$_.JObject { .boolean; } - static final _id_getFileStreamPath = _class.instanceMethodId( - r'getFileStreamPath', - r'(Ljava/lang/String;)Ljava/io/File;', + static final _id_deleteSharedPreferences = _class.instanceMethodId( + r'deleteSharedPreferences', + r'(Ljava/lang/String;)Z', ); - static final _getFileStreamPath = jni$_.ProtectedJniExtensions.lookup< + static final _deleteSharedPreferences = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + 'globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract java.io.File getFileStreamPath(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getFileStreamPath( + /// from: `public abstract boolean deleteSharedPreferences(java.lang.String string)` + bool deleteSharedPreferences( jni$_.JString? string, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _getFileStreamPath(reference.pointer, - _id_getFileStreamPath as jni$_.JMethodIDPtr, _$string.pointer) - .object(const jni$_.JObjectNullableType()); - } - - static final _id_getDataDir = _class.instanceMethodId( - r'getDataDir', - r'()Ljava/io/File;', - ); - - static final _getDataDir = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public abstract java.io.File getDataDir()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getDataDir() { - return _getDataDir(reference.pointer, _id_getDataDir as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + return _deleteSharedPreferences(reference.pointer, + _id_deleteSharedPreferences as jni$_.JMethodIDPtr, _$string.pointer) + .boolean; } - static final _id_getFilesDir = _class.instanceMethodId( - r'getFilesDir', - r'()Ljava/io/File;', + static final _id_enforceCallingOrSelfPermission = _class.instanceMethodId( + r'enforceCallingOrSelfPermission', + r'(Ljava/lang/String;Ljava/lang/String;)V', ); - static final _getFilesDir = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + static final _enforceCallingOrSelfPermission = + 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 abstract java.io.File getFilesDir()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getFilesDir() { - return _getFilesDir( - reference.pointer, _id_getFilesDir as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public abstract void enforceCallingOrSelfPermission(java.lang.String string, java.lang.String string1)` + void enforceCallingOrSelfPermission( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _enforceCallingOrSelfPermission( + reference.pointer, + _id_enforceCallingOrSelfPermission as jni$_.JMethodIDPtr, + _$string.pointer, + _$string1.pointer) + .check(); } - static final _id_getNoBackupFilesDir = _class.instanceMethodId( - r'getNoBackupFilesDir', - r'()Ljava/io/File;', + static final _id_enforceCallingOrSelfUriPermission = _class.instanceMethodId( + r'enforceCallingOrSelfUriPermission', + r'(Landroid/net/Uri;ILjava/lang/String;)V', ); - static final _getNoBackupFilesDir = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + static final _enforceCallingOrSelfUriPermission = + jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + jni$_.Pointer)>(); + + /// from: `public abstract void enforceCallingOrSelfUriPermission(android.net.Uri uri, int i, java.lang.String string)` + void enforceCallingOrSelfUriPermission( + jni$_.JObject? uri, + int i, + jni$_.JString? string, + ) { + final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + _enforceCallingOrSelfUriPermission( + reference.pointer, + _id_enforceCallingOrSelfUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, + i, + _$string.pointer) + .check(); + } + + static final _id_enforceCallingPermission = _class.instanceMethodId( + r'enforceCallingPermission', + r'(Ljava/lang/String;Ljava/lang/String;)V', + ); + + static final _enforceCallingPermission = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract java.io.File getNoBackupFilesDir()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getNoBackupFilesDir() { - return _getNoBackupFilesDir( - reference.pointer, _id_getNoBackupFilesDir as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + /// from: `public abstract void enforceCallingPermission(java.lang.String string, java.lang.String string1)` + void enforceCallingPermission( + jni$_.JString? string, + jni$_.JString? string1, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _enforceCallingPermission( + reference.pointer, + _id_enforceCallingPermission as jni$_.JMethodIDPtr, + _$string.pointer, + _$string1.pointer) + .check(); } - static final _id_getExternalFilesDir = _class.instanceMethodId( - r'getExternalFilesDir', - r'(Ljava/lang/String;)Ljava/io/File;', + static final _id_enforceCallingUriPermission = _class.instanceMethodId( + r'enforceCallingUriPermission', + r'(Landroid/net/Uri;ILjava/lang/String;)V', ); - static final _getExternalFilesDir = jni$_.ProtectedJniExtensions.lookup< + static final _enforceCallingUriPermission = + jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + jni$_.Pointer)>(); + + /// from: `public abstract void enforceCallingUriPermission(android.net.Uri uri, int i, java.lang.String string)` + void enforceCallingUriPermission( + jni$_.JObject? uri, + int i, + jni$_.JString? string, + ) { + final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + _enforceCallingUriPermission( + reference.pointer, + _id_enforceCallingUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, + i, + _$string.pointer) + .check(); + } + + static final _id_enforcePermission = _class.instanceMethodId( + r'enforcePermission', + r'(Ljava/lang/String;IILjava/lang/String;)V', + ); + + static final _enforcePermission = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + int, + jni$_.Pointer)>(); - /// from: `public abstract java.io.File getExternalFilesDir(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getExternalFilesDir( + /// from: `public abstract void enforcePermission(java.lang.String string, int i, int i1, java.lang.String string1)` + void enforcePermission( jni$_.JString? string, + int i, + int i1, + jni$_.JString? string1, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _getExternalFilesDir(reference.pointer, - _id_getExternalFilesDir as jni$_.JMethodIDPtr, _$string.pointer) - .object(const jni$_.JObjectNullableType()); + final _$string1 = string1?.reference ?? jni$_.jNullReference; + _enforcePermission( + reference.pointer, + _id_enforcePermission as jni$_.JMethodIDPtr, + _$string.pointer, + i, + i1, + _$string1.pointer) + .check(); } - static final _id_getExternalFilesDirs = _class.instanceMethodId( - r'getExternalFilesDirs', - r'(Ljava/lang/String;)[Ljava/io/File;', + static final _id_enforceUriPermission = _class.instanceMethodId( + r'enforceUriPermission', + r'(Landroid/net/Uri;IIILjava/lang/String;)V', ); - static final _getExternalFilesDirs = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + static final _enforceUriPermission = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + int, + int, + int, + jni$_.Pointer)>(); - /// from: `public abstract java.io.File[] getExternalFilesDirs(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? getExternalFilesDirs( + /// from: `public abstract void enforceUriPermission(android.net.Uri uri, int i, int i1, int i2, java.lang.String string)` + void enforceUriPermission( + jni$_.JObject? uri, + int i, + int i1, + int i2, jni$_.JString? string, ) { + final _$uri = uri?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - return _getExternalFilesDirs(reference.pointer, - _id_getExternalFilesDirs as jni$_.JMethodIDPtr, _$string.pointer) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JObjectNullableType())); + _enforceUriPermission( + reference.pointer, + _id_enforceUriPermission as jni$_.JMethodIDPtr, + _$uri.pointer, + i, + i1, + i2, + _$string.pointer) + .check(); } - static final _id_getObbDir = _class.instanceMethodId( - r'getObbDir', - r'()Ljava/io/File;', + static final _id_enforceUriPermission$1 = _class.instanceMethodId( + r'enforceUriPermission', + r'(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;)V', ); - static final _getObbDir = jni$_.ProtectedJniExtensions.lookup< + static final _enforceUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + int, + int, + int, + jni$_.Pointer)>(); + + /// from: `public abstract void enforceUriPermission(android.net.Uri uri, java.lang.String string, java.lang.String string1, int i, int i1, int i2, java.lang.String string2)` + void enforceUriPermission$1( + jni$_.JObject? uri, + jni$_.JString? string, + jni$_.JString? string1, + int i, + int i1, + int i2, + jni$_.JString? string2, + ) { + final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + final _$string2 = string2?.reference ?? jni$_.jNullReference; + _enforceUriPermission$1( + reference.pointer, + _id_enforceUriPermission$1 as jni$_.JMethodIDPtr, + _$uri.pointer, + _$string.pointer, + _$string1.pointer, + i, + i1, + i2, + _$string2.pointer) + .check(); + } + + static final _id_fileList = _class.instanceMethodId( + r'fileList', + r'()[Ljava/lang/String;', + ); + + static final _fileList = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44437,19 +45004,21 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File getObbDir()` + /// from: `public abstract java.lang.String[] fileList()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getObbDir() { - return _getObbDir(reference.pointer, _id_getObbDir as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); + jni$_.JArray? fileList() { + return _fileList(reference.pointer, _id_fileList as jni$_.JMethodIDPtr) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JStringNullableType())); } - static final _id_getObbDirs = _class.instanceMethodId( - r'getObbDirs', - r'()[Ljava/io/File;', + static final _id_getApplicationContext = _class.instanceMethodId( + r'getApplicationContext', + r'()Landroid/content/Context;', ); - static final _getObbDirs = jni$_.ProtectedJniExtensions.lookup< + static final _getApplicationContext = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44461,21 +45030,20 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File[] getObbDirs()` + /// from: `public abstract android.content.Context getApplicationContext()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? getObbDirs() { - return _getObbDirs(reference.pointer, _id_getObbDirs as jni$_.JMethodIDPtr) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JObjectNullableType())); + Context? getApplicationContext() { + return _getApplicationContext( + reference.pointer, _id_getApplicationContext as jni$_.JMethodIDPtr) + .object(const $Context$NullableType()); } - static final _id_getCacheDir = _class.instanceMethodId( - r'getCacheDir', - r'()Ljava/io/File;', + static final _id_getApplicationInfo = _class.instanceMethodId( + r'getApplicationInfo', + r'()Landroid/content/pm/ApplicationInfo;', ); - static final _getCacheDir = jni$_.ProtectedJniExtensions.lookup< + static final _getApplicationInfo = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44487,20 +45055,20 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File getCacheDir()` + /// from: `public abstract android.content.pm.ApplicationInfo getApplicationInfo()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getCacheDir() { - return _getCacheDir( - reference.pointer, _id_getCacheDir as jni$_.JMethodIDPtr) + jni$_.JObject? getApplicationInfo() { + return _getApplicationInfo( + reference.pointer, _id_getApplicationInfo as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_getCodeCacheDir = _class.instanceMethodId( - r'getCodeCacheDir', - r'()Ljava/io/File;', + static final _id_getAssets = _class.instanceMethodId( + r'getAssets', + r'()Landroid/content/res/AssetManager;', ); - static final _getCodeCacheDir = jni$_.ProtectedJniExtensions.lookup< + static final _getAssets = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44512,20 +45080,19 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File getCodeCacheDir()` + /// from: `public abstract android.content.res.AssetManager getAssets()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getCodeCacheDir() { - return _getCodeCacheDir( - reference.pointer, _id_getCodeCacheDir as jni$_.JMethodIDPtr) + jni$_.JObject? getAssets() { + return _getAssets(reference.pointer, _id_getAssets as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_getExternalCacheDir = _class.instanceMethodId( - r'getExternalCacheDir', - r'()Ljava/io/File;', + static final _id_getAttributionSource = _class.instanceMethodId( + r'getAttributionSource', + r'()Landroid/content/AttributionSource;', ); - static final _getExternalCacheDir = jni$_.ProtectedJniExtensions.lookup< + static final _getAttributionSource = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44537,20 +45104,20 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File getExternalCacheDir()` + /// from: `public android.content.AttributionSource getAttributionSource()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getExternalCacheDir() { - return _getExternalCacheDir( - reference.pointer, _id_getExternalCacheDir as jni$_.JMethodIDPtr) + jni$_.JObject? getAttributionSource() { + return _getAttributionSource( + reference.pointer, _id_getAttributionSource as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_getExternalCacheDirs = _class.instanceMethodId( - r'getExternalCacheDirs', - r'()[Ljava/io/File;', + static final _id_getAttributionTag = _class.instanceMethodId( + r'getAttributionTag', + r'()Ljava/lang/String;', ); - static final _getExternalCacheDirs = jni$_.ProtectedJniExtensions.lookup< + static final _getAttributionTag = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44562,22 +45129,20 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File[] getExternalCacheDirs()` + /// from: `public java.lang.String getAttributionTag()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? getExternalCacheDirs() { - return _getExternalCacheDirs( - reference.pointer, _id_getExternalCacheDirs as jni$_.JMethodIDPtr) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JObjectNullableType())); + jni$_.JString? getAttributionTag() { + return _getAttributionTag( + reference.pointer, _id_getAttributionTag as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); } - static final _id_getExternalMediaDirs = _class.instanceMethodId( - r'getExternalMediaDirs', - r'()[Ljava/io/File;', + static final _id_getCacheDir = _class.instanceMethodId( + r'getCacheDir', + r'()Ljava/io/File;', ); - static final _getExternalMediaDirs = jni$_.ProtectedJniExtensions.lookup< + static final _getCacheDir = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44589,22 +45154,20 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.io.File[] getExternalMediaDirs()` + /// from: `public abstract java.io.File getCacheDir()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? getExternalMediaDirs() { - return _getExternalMediaDirs( - reference.pointer, _id_getExternalMediaDirs as jni$_.JMethodIDPtr) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JObjectNullableType())); + jni$_.JObject? getCacheDir() { + return _getCacheDir( + reference.pointer, _id_getCacheDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_fileList = _class.instanceMethodId( - r'fileList', - r'()[Ljava/lang/String;', + static final _id_getClassLoader = _class.instanceMethodId( + r'getClassLoader', + r'()Ljava/lang/ClassLoader;', ); - static final _fileList = jni$_.ProtectedJniExtensions.lookup< + static final _getClassLoader = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44616,195 +45179,134 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.lang.String[] fileList()` + /// from: `public abstract java.lang.ClassLoader getClassLoader()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? fileList() { - return _fileList(reference.pointer, _id_fileList as jni$_.JMethodIDPtr) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JStringNullableType())); + jni$_.JObject? getClassLoader() { + return _getClassLoader( + reference.pointer, _id_getClassLoader as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_getDir = _class.instanceMethodId( - r'getDir', - r'(Ljava/lang/String;I)Ljava/io/File;', + static final _id_getCodeCacheDir = _class.instanceMethodId( + r'getCodeCacheDir', + r'()Ljava/io/File;', ); - static final _getDir = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallObjectMethod') + static final _getCodeCacheDir = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract java.io.File getDir(java.lang.String string, int i)` + /// from: `public abstract java.io.File getCodeCacheDir()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getDir( - jni$_.JString? string, - int i, - ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _getDir(reference.pointer, _id_getDir as jni$_.JMethodIDPtr, - _$string.pointer, i) + jni$_.JObject? getCodeCacheDir() { + return _getCodeCacheDir( + reference.pointer, _id_getCodeCacheDir as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_openOrCreateDatabase = _class.instanceMethodId( - r'openOrCreateDatabase', - r'(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;)Landroid/database/sqlite/SQLiteDatabase;', + static final _id_getColor = _class.instanceMethodId( + r'getColor', + r'(I)I', ); - static final _openOrCreateDatabase = jni$_.ProtectedJniExtensions.lookup< + static final _getColor = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - jni$_.Pointer)>(); + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String string, int i, android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? openOrCreateDatabase( - jni$_.JString? string, + /// from: `public final int getColor(int i)` + int getColor( int i, - jni$_.JObject? cursorFactory, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - final _$cursorFactory = cursorFactory?.reference ?? jni$_.jNullReference; - return _openOrCreateDatabase( - reference.pointer, - _id_openOrCreateDatabase as jni$_.JMethodIDPtr, - _$string.pointer, - i, - _$cursorFactory.pointer) - .object(const jni$_.JObjectNullableType()); + return _getColor(reference.pointer, _id_getColor as jni$_.JMethodIDPtr, i) + .integer; } - static final _id_openOrCreateDatabase$1 = _class.instanceMethodId( - r'openOrCreateDatabase', - r'(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;)Landroid/database/sqlite/SQLiteDatabase;', + static final _id_getColorStateList = _class.instanceMethodId( + r'getColorStateList', + r'(I)Landroid/content/res/ColorStateList;', ); - static final _openOrCreateDatabase$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getColorStateList = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String string, int i, android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, android.database.DatabaseErrorHandler databaseErrorHandler)` + /// from: `public final android.content.res.ColorStateList getColorStateList(int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? openOrCreateDatabase$1( - jni$_.JString? string, + jni$_.JObject? getColorStateList( int i, - jni$_.JObject? cursorFactory, - jni$_.JObject? databaseErrorHandler, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - final _$cursorFactory = cursorFactory?.reference ?? jni$_.jNullReference; - final _$databaseErrorHandler = - databaseErrorHandler?.reference ?? jni$_.jNullReference; - return _openOrCreateDatabase$1( - reference.pointer, - _id_openOrCreateDatabase$1 as jni$_.JMethodIDPtr, - _$string.pointer, - i, - _$cursorFactory.pointer, - _$databaseErrorHandler.pointer) + return _getColorStateList( + reference.pointer, _id_getColorStateList as jni$_.JMethodIDPtr, i) .object(const jni$_.JObjectNullableType()); } - static final _id_moveDatabaseFrom = _class.instanceMethodId( - r'moveDatabaseFrom', - r'(Landroid/content/Context;Ljava/lang/String;)Z', + static final _id_getContentResolver = _class.instanceMethodId( + r'getContentResolver', + r'()Landroid/content/ContentResolver;', ); - static final _moveDatabaseFrom = jni$_.ProtectedJniExtensions.lookup< + static final _getContentResolver = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract boolean moveDatabaseFrom(android.content.Context context, java.lang.String string)` - bool moveDatabaseFrom( - Context? context, - jni$_.JString? string, - ) { - final _$context = context?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - return _moveDatabaseFrom( - reference.pointer, - _id_moveDatabaseFrom as jni$_.JMethodIDPtr, - _$context.pointer, - _$string.pointer) - .boolean; + /// from: `public abstract android.content.ContentResolver getContentResolver()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getContentResolver() { + return _getContentResolver( + reference.pointer, _id_getContentResolver as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_deleteDatabase = _class.instanceMethodId( - r'deleteDatabase', - r'(Ljava/lang/String;)Z', + static final _id_getDataDir = _class.instanceMethodId( + r'getDataDir', + r'()Ljava/io/File;', ); - static final _deleteDatabase = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallBooleanMethod') + static final _getDataDir = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract boolean deleteDatabase(java.lang.String string)` - bool deleteDatabase( - jni$_.JString? string, - ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _deleteDatabase(reference.pointer, - _id_deleteDatabase as jni$_.JMethodIDPtr, _$string.pointer) - .boolean; + /// from: `public abstract java.io.File getDataDir()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getDataDir() { + return _getDataDir(reference.pointer, _id_getDataDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } static final _id_getDatabasePath = _class.instanceMethodId( @@ -44834,39 +45336,65 @@ class Context extends jni$_.JObject { .object(const jni$_.JObjectNullableType()); } - static final _id_databaseList = _class.instanceMethodId( - r'databaseList', - r'()[Ljava/lang/String;', + static final _id_getDeviceId = _class.instanceMethodId( + r'getDeviceId', + r'()I', ); - static final _databaseList = jni$_.ProtectedJniExtensions.lookup< + static final _getDeviceId = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + )>>('globalEnv_CallIntMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public abstract java.lang.String[] databaseList()` + /// from: `public int getDeviceId()` + int getDeviceId() { + return _getDeviceId( + reference.pointer, _id_getDeviceId as jni$_.JMethodIDPtr) + .integer; + } + + static final _id_getDir = _class.instanceMethodId( + r'getDir', + r'(Ljava/lang/String;I)Ljava/io/File;', + ); + + static final _getDir = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + + /// from: `public abstract java.io.File getDir(java.lang.String string, int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JArray? databaseList() { - return _databaseList( - reference.pointer, _id_databaseList as jni$_.JMethodIDPtr) - .object?>( - const jni$_.JArrayNullableType( - jni$_.JStringNullableType())); + jni$_.JObject? getDir( + jni$_.JString? string, + int i, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return _getDir(reference.pointer, _id_getDir as jni$_.JMethodIDPtr, + _$string.pointer, i) + .object(const jni$_.JObjectNullableType()); } - static final _id_getWallpaper = _class.instanceMethodId( - r'getWallpaper', - r'()Landroid/graphics/drawable/Drawable;', + static final _id_getDisplay = _class.instanceMethodId( + r'getDisplay', + r'()Landroid/view/Display;', ); - static final _getWallpaper = jni$_.ProtectedJniExtensions.lookup< + static final _getDisplay = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -44878,1112 +45406,817 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, )>(); - /// from: `public abstract android.graphics.drawable.Drawable getWallpaper()` + /// from: `public android.view.Display getDisplay()` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getWallpaper() { - return _getWallpaper( - reference.pointer, _id_getWallpaper as jni$_.JMethodIDPtr) + jni$_.JObject? getDisplay() { + return _getDisplay(reference.pointer, _id_getDisplay as jni$_.JMethodIDPtr) .object(const jni$_.JObjectNullableType()); } - static final _id_peekWallpaper = _class.instanceMethodId( - r'peekWallpaper', - r'()Landroid/graphics/drawable/Drawable;', + static final _id_getDrawable = _class.instanceMethodId( + r'getDrawable', + r'(I)Landroid/graphics/drawable/Drawable;', ); - static final _peekWallpaper = jni$_.ProtectedJniExtensions.lookup< + static final _getDrawable = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract android.graphics.drawable.Drawable peekWallpaper()` + /// from: `public final android.graphics.drawable.Drawable getDrawable(int i)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? peekWallpaper() { - return _peekWallpaper( - reference.pointer, _id_peekWallpaper as jni$_.JMethodIDPtr) + jni$_.JObject? getDrawable( + int i, + ) { + return _getDrawable( + reference.pointer, _id_getDrawable as jni$_.JMethodIDPtr, i) .object(const jni$_.JObjectNullableType()); } - static final _id_getWallpaperDesiredMinimumWidth = _class.instanceMethodId( - r'getWallpaperDesiredMinimumWidth', - r'()I', + static final _id_getExternalCacheDir = _class.instanceMethodId( + r'getExternalCacheDir', + r'()Ljava/io/File;', ); - static final _getWallpaperDesiredMinimumWidth = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') - .asFunction< + static final _getExternalCacheDir = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>(); + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract int getWallpaperDesiredMinimumWidth()` - int getWallpaperDesiredMinimumWidth() { - return _getWallpaperDesiredMinimumWidth(reference.pointer, - _id_getWallpaperDesiredMinimumWidth as jni$_.JMethodIDPtr) - .integer; + /// from: `public abstract java.io.File getExternalCacheDir()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getExternalCacheDir() { + return _getExternalCacheDir( + reference.pointer, _id_getExternalCacheDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_getWallpaperDesiredMinimumHeight = _class.instanceMethodId( - r'getWallpaperDesiredMinimumHeight', - r'()I', + static final _id_getExternalCacheDirs = _class.instanceMethodId( + r'getExternalCacheDirs', + r'()[Ljava/io/File;', ); - static final _getWallpaperDesiredMinimumHeight = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') - .asFunction< + static final _getExternalCacheDirs = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>(); + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract int getWallpaperDesiredMinimumHeight()` - int getWallpaperDesiredMinimumHeight() { - return _getWallpaperDesiredMinimumHeight(reference.pointer, - _id_getWallpaperDesiredMinimumHeight as jni$_.JMethodIDPtr) - .integer; + /// from: `public abstract java.io.File[] getExternalCacheDirs()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JArray? getExternalCacheDirs() { + return _getExternalCacheDirs( + reference.pointer, _id_getExternalCacheDirs as jni$_.JMethodIDPtr) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JObjectNullableType())); } - static final _id_setWallpaper = _class.instanceMethodId( - r'setWallpaper', - r'(Landroid/graphics/Bitmap;)V', + static final _id_getExternalFilesDir = _class.instanceMethodId( + r'getExternalFilesDir', + r'(Ljava/lang/String;)Ljava/io/File;', ); - static final _setWallpaper = jni$_.ProtectedJniExtensions.lookup< + static final _getExternalFilesDir = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void setWallpaper(android.graphics.Bitmap bitmap)` - void setWallpaper( - Bitmap? bitmap, + /// from: `public abstract java.io.File getExternalFilesDir(java.lang.String string)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getExternalFilesDir( + jni$_.JString? string, ) { - final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; - _setWallpaper(reference.pointer, _id_setWallpaper as jni$_.JMethodIDPtr, - _$bitmap.pointer) - .check(); + final _$string = string?.reference ?? jni$_.jNullReference; + return _getExternalFilesDir(reference.pointer, + _id_getExternalFilesDir as jni$_.JMethodIDPtr, _$string.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_setWallpaper$1 = _class.instanceMethodId( - r'setWallpaper', - r'(Ljava/io/InputStream;)V', + static final _id_getExternalFilesDirs = _class.instanceMethodId( + r'getExternalFilesDirs', + r'(Ljava/lang/String;)[Ljava/io/File;', ); - static final _setWallpaper$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getExternalFilesDirs = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void setWallpaper(java.io.InputStream inputStream)` - void setWallpaper$1( - jni$_.JObject? inputStream, + /// from: `public abstract java.io.File[] getExternalFilesDirs(java.lang.String string)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JArray? getExternalFilesDirs( + jni$_.JString? string, ) { - final _$inputStream = inputStream?.reference ?? jni$_.jNullReference; - _setWallpaper$1(reference.pointer, _id_setWallpaper$1 as jni$_.JMethodIDPtr, - _$inputStream.pointer) - .check(); + final _$string = string?.reference ?? jni$_.jNullReference; + return _getExternalFilesDirs(reference.pointer, + _id_getExternalFilesDirs as jni$_.JMethodIDPtr, _$string.pointer) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JObjectNullableType())); } - static final _id_clearWallpaper = _class.instanceMethodId( - r'clearWallpaper', - r'()V', + static final _id_getExternalMediaDirs = _class.instanceMethodId( + r'getExternalMediaDirs', + r'()[Ljava/io/File;', ); - static final _clearWallpaper = jni$_.ProtectedJniExtensions.lookup< + static final _getExternalMediaDirs = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - )>>('globalEnv_CallVoidMethod') + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, )>(); - /// from: `public abstract void clearWallpaper()` - void clearWallpaper() { - _clearWallpaper(reference.pointer, _id_clearWallpaper as jni$_.JMethodIDPtr) - .check(); + /// from: `public abstract java.io.File[] getExternalMediaDirs()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JArray? getExternalMediaDirs() { + return _getExternalMediaDirs( + reference.pointer, _id_getExternalMediaDirs as jni$_.JMethodIDPtr) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JObjectNullableType())); } - static final _id_startActivity = _class.instanceMethodId( - r'startActivity', - r'(Landroid/content/Intent;)V', + static final _id_getFileStreamPath = _class.instanceMethodId( + r'getFileStreamPath', + r'(Ljava/lang/String;)Ljava/io/File;', ); - static final _startActivity = jni$_.ProtectedJniExtensions.lookup< + static final _getFileStreamPath = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void startActivity(android.content.Intent intent)` - void startActivity( - jni$_.JObject? intent, + /// from: `public abstract java.io.File getFileStreamPath(java.lang.String string)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getFileStreamPath( + jni$_.JString? string, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - _startActivity(reference.pointer, _id_startActivity as jni$_.JMethodIDPtr, - _$intent.pointer) - .check(); + final _$string = string?.reference ?? jni$_.jNullReference; + return _getFileStreamPath(reference.pointer, + _id_getFileStreamPath as jni$_.JMethodIDPtr, _$string.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_startActivity$1 = _class.instanceMethodId( - r'startActivity', - r'(Landroid/content/Intent;Landroid/os/Bundle;)V', + static final _id_getFilesDir = _class.instanceMethodId( + r'getFilesDir', + r'()Ljava/io/File;', ); - static final _startActivity$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getFilesDir = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void startActivity(android.content.Intent intent, android.os.Bundle bundle)` - void startActivity$1( - jni$_.JObject? intent, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _startActivity$1( - reference.pointer, - _id_startActivity$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract java.io.File getFilesDir()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getFilesDir() { + return _getFilesDir( + reference.pointer, _id_getFilesDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_startActivities = _class.instanceMethodId( - r'startActivities', - r'([Landroid/content/Intent;)V', + static final _id_getMainExecutor = _class.instanceMethodId( + r'getMainExecutor', + r'()Ljava/util/concurrent/Executor;', ); - static final _startActivities = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + static final _getMainExecutor = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void startActivities(android.content.Intent[] intents)` - void startActivities( - jni$_.JArray? intents, - ) { - final _$intents = intents?.reference ?? jni$_.jNullReference; - _startActivities(reference.pointer, - _id_startActivities as jni$_.JMethodIDPtr, _$intents.pointer) - .check(); + /// from: `public java.util.concurrent.Executor getMainExecutor()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getMainExecutor() { + return _getMainExecutor( + reference.pointer, _id_getMainExecutor as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_startActivities$1 = _class.instanceMethodId( - r'startActivities', - r'([Landroid/content/Intent;Landroid/os/Bundle;)V', + static final _id_getMainLooper = _class.instanceMethodId( + r'getMainLooper', + r'()Landroid/os/Looper;', ); - static final _startActivities$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getMainLooper = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void startActivities(android.content.Intent[] intents, android.os.Bundle bundle)` - void startActivities$1( - jni$_.JArray? intents, - jni$_.JObject? bundle, - ) { - final _$intents = intents?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _startActivities$1( - reference.pointer, - _id_startActivities$1 as jni$_.JMethodIDPtr, - _$intents.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract android.os.Looper getMainLooper()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getMainLooper() { + return _getMainLooper( + reference.pointer, _id_getMainLooper as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_startIntentSender = _class.instanceMethodId( - r'startIntentSender', - r'(Landroid/content/IntentSender;Landroid/content/Intent;III)V', + static final _id_getNoBackupFilesDir = _class.instanceMethodId( + r'getNoBackupFilesDir', + r'()Ljava/io/File;', ); - static final _startIntentSender = jni$_.ProtectedJniExtensions.lookup< + static final _getNoBackupFilesDir = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - int, - int, - int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void startIntentSender(android.content.IntentSender intentSender, android.content.Intent intent, int i, int i1, int i2)` - void startIntentSender( - jni$_.JObject? intentSender, - jni$_.JObject? intent, - int i, - int i1, - int i2, - ) { - final _$intentSender = intentSender?.reference ?? jni$_.jNullReference; - final _$intent = intent?.reference ?? jni$_.jNullReference; - _startIntentSender( - reference.pointer, - _id_startIntentSender as jni$_.JMethodIDPtr, - _$intentSender.pointer, - _$intent.pointer, - i, - i1, - i2) - .check(); + /// from: `public abstract java.io.File getNoBackupFilesDir()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getNoBackupFilesDir() { + return _getNoBackupFilesDir( + reference.pointer, _id_getNoBackupFilesDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_startIntentSender$1 = _class.instanceMethodId( - r'startIntentSender', - r'(Landroid/content/IntentSender;Landroid/content/Intent;IIILandroid/os/Bundle;)V', + static final _id_getObbDir = _class.instanceMethodId( + r'getObbDir', + r'()Ljava/io/File;', ); - static final _startIntentSender$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getObbDir = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - int, - int, - int, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void startIntentSender(android.content.IntentSender intentSender, android.content.Intent intent, int i, int i1, int i2, android.os.Bundle bundle)` - void startIntentSender$1( - jni$_.JObject? intentSender, - jni$_.JObject? intent, - int i, - int i1, - int i2, - jni$_.JObject? bundle, - ) { - final _$intentSender = intentSender?.reference ?? jni$_.jNullReference; - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _startIntentSender$1( - reference.pointer, - _id_startIntentSender$1 as jni$_.JMethodIDPtr, - _$intentSender.pointer, - _$intent.pointer, - i, - i1, - i2, - _$bundle.pointer) - .check(); + /// from: `public abstract java.io.File getObbDir()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getObbDir() { + return _getObbDir(reference.pointer, _id_getObbDir as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendBroadcast = _class.instanceMethodId( - r'sendBroadcast', - r'(Landroid/content/Intent;)V', + static final _id_getObbDirs = _class.instanceMethodId( + r'getObbDirs', + r'()[Ljava/io/File;', ); - static final _sendBroadcast = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + static final _getObbDirs = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendBroadcast(android.content.Intent intent)` - void sendBroadcast( - jni$_.JObject? intent, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - _sendBroadcast(reference.pointer, _id_sendBroadcast as jni$_.JMethodIDPtr, - _$intent.pointer) - .check(); + /// from: `public abstract java.io.File[] getObbDirs()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JArray? getObbDirs() { + return _getObbDirs(reference.pointer, _id_getObbDirs as jni$_.JMethodIDPtr) + .object?>( + const jni$_.JArrayNullableType( + jni$_.JObjectNullableType())); } - static final _id_sendBroadcast$1 = _class.instanceMethodId( - r'sendBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;)V', + static final _id_getOpPackageName = _class.instanceMethodId( + r'getOpPackageName', + r'()Ljava/lang/String;', ); - static final _sendBroadcast$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getOpPackageName = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendBroadcast(android.content.Intent intent, java.lang.String string)` - void sendBroadcast$1( - jni$_.JObject? intent, - jni$_.JString? string, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - _sendBroadcast$1( - reference.pointer, - _id_sendBroadcast$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer) - .check(); + /// from: `public java.lang.String getOpPackageName()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getOpPackageName() { + return _getOpPackageName( + reference.pointer, _id_getOpPackageName as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); } - static final _id_sendBroadcastWithMultiplePermissions = - _class.instanceMethodId( - r'sendBroadcastWithMultiplePermissions', - r'(Landroid/content/Intent;[Ljava/lang/String;)V', + static final _id_getPackageCodePath = _class.instanceMethodId( + r'getPackageCodePath', + r'()Ljava/lang/String;', ); - static final _sendBroadcastWithMultiplePermissions = - 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)>(); + static final _getPackageCodePath = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void sendBroadcastWithMultiplePermissions(android.content.Intent intent, java.lang.String[] strings)` - void sendBroadcastWithMultiplePermissions( - jni$_.JObject? intent, - jni$_.JArray? strings, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$strings = strings?.reference ?? jni$_.jNullReference; - _sendBroadcastWithMultiplePermissions( - reference.pointer, - _id_sendBroadcastWithMultiplePermissions as jni$_.JMethodIDPtr, - _$intent.pointer, - _$strings.pointer) - .check(); + /// from: `public abstract java.lang.String getPackageCodePath()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getPackageCodePath() { + return _getPackageCodePath( + reference.pointer, _id_getPackageCodePath as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); } - static final _id_sendBroadcast$2 = _class.instanceMethodId( - r'sendBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;)V', + static final _id_getPackageManager = _class.instanceMethodId( + r'getPackageManager', + r'()Landroid/content/pm/PackageManager;', ); - static final _sendBroadcast$2 = jni$_.ProtectedJniExtensions.lookup< + static final _getPackageManager = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void sendBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle)` - void sendBroadcast$2( - jni$_.JObject? intent, - jni$_.JString? string, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendBroadcast$2( - reference.pointer, - _id_sendBroadcast$2 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract android.content.pm.PackageManager getPackageManager()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getPackageManager() { + return _getPackageManager( + reference.pointer, _id_getPackageManager as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendOrderedBroadcast = _class.instanceMethodId( - r'sendOrderedBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;)V', + static final _id_getPackageName = _class.instanceMethodId( + r'getPackageName', + r'()Ljava/lang/String;', ); - static final _sendOrderedBroadcast = jni$_.ProtectedJniExtensions.lookup< + static final _getPackageName = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string)` - void sendOrderedBroadcast( - jni$_.JObject? intent, - jni$_.JString? string, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcast( - reference.pointer, - _id_sendOrderedBroadcast as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer) - .check(); + /// from: `public abstract java.lang.String getPackageName()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getPackageName() { + return _getPackageName( + reference.pointer, _id_getPackageName as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); } - static final _id_sendOrderedBroadcast$1 = _class.instanceMethodId( - r'sendOrderedBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;)V', + static final _id_getPackageResourcePath = _class.instanceMethodId( + r'getPackageResourcePath', + r'()Ljava/lang/String;', ); - static final _sendOrderedBroadcast$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getPackageResourcePath = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle)` - void sendOrderedBroadcast$1( - jni$_.JObject? intent, - jni$_.JString? string, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcast$1( - reference.pointer, - _id_sendOrderedBroadcast$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract java.lang.String getPackageResourcePath()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getPackageResourcePath() { + return _getPackageResourcePath( + reference.pointer, _id_getPackageResourcePath as jni$_.JMethodIDPtr) + .object(const jni$_.JStringNullableType()); } - static final _id_sendOrderedBroadcast$2 = _class.instanceMethodId( - r'sendOrderedBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_getParams = _class.instanceMethodId( + r'getParams', + r'()Landroid/content/ContextParams;', ); - static final _sendOrderedBroadcast$2 = jni$_.ProtectedJniExtensions.lookup< + static final _getParams = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle)` - void sendOrderedBroadcast$2( - jni$_.JObject? intent, - jni$_.JString? string, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, - int i, - jni$_.JString? string1, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcast$2( - reference.pointer, - _id_sendOrderedBroadcast$2 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string1.pointer, - _$bundle.pointer) - .check(); + /// from: `public android.content.ContextParams getParams()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getParams() { + return _getParams(reference.pointer, _id_getParams as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendOrderedBroadcast$3 = _class.instanceMethodId( - r'sendOrderedBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_getResources = _class.instanceMethodId( + r'getResources', + r'()Landroid/content/res/Resources;', ); - static final _sendOrderedBroadcast$3 = jni$_.ProtectedJniExtensions.lookup< + static final _getResources = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle1)` - void sendOrderedBroadcast$3( - jni$_.JObject? intent, + /// from: `public abstract android.content.res.Resources getResources()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getResources() { + return _getResources( + reference.pointer, _id_getResources as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_getSharedPreferences = _class.instanceMethodId( + r'getSharedPreferences', + r'(Ljava/lang/String;I)Landroid/content/SharedPreferences;', + ); + + static final _getSharedPreferences = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + + /// from: `public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String string, int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getSharedPreferences( jni$_.JString? string, - jni$_.JObject? bundle, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, int i, - jni$_.JString? string1, - jni$_.JObject? bundle1, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - final _$bundle1 = bundle1?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcast$3( - reference.pointer, - _id_sendOrderedBroadcast$3 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer, - _$bundle.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string1.pointer, - _$bundle1.pointer) - .check(); + return _getSharedPreferences(reference.pointer, + _id_getSharedPreferences as jni$_.JMethodIDPtr, _$string.pointer, i) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendBroadcastAsUser = _class.instanceMethodId( - r'sendBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', + static final _id_getString = _class.instanceMethodId( + r'getString', + r'(I)Ljava/lang/String;', ); - static final _sendBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< + static final _getString = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract void sendBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` - void sendBroadcastAsUser( - jni$_.JObject? intent, - jni$_.JObject? userHandle, + /// from: `public final java.lang.String getString(int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getString( + int i, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - _sendBroadcastAsUser( - reference.pointer, - _id_sendBroadcastAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer) - .check(); + return _getString(reference.pointer, _id_getString as jni$_.JMethodIDPtr, i) + .object(const jni$_.JStringNullableType()); } - static final _id_sendBroadcastAsUser$1 = _class.instanceMethodId( - r'sendBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;)V', + static final _id_getString$1 = _class.instanceMethodId( + r'getString', + r'(I[Ljava/lang/Object;)Ljava/lang/String;', ); - static final _sendBroadcastAsUser$1 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + static final _getString$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_ + .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); - /// from: `public abstract void sendBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, java.lang.String string)` - void sendBroadcastAsUser$1( - jni$_.JObject? intent, - jni$_.JObject? userHandle, - jni$_.JString? string, + /// from: `public final java.lang.String getString(int i, java.lang.Object[] objects)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getString$1( + int i, + jni$_.JArray? objects, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - _sendBroadcastAsUser$1( - reference.pointer, - _id_sendBroadcastAsUser$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer, - _$string.pointer) - .check(); + final _$objects = objects?.reference ?? jni$_.jNullReference; + return _getString$1(reference.pointer, + _id_getString$1 as jni$_.JMethodIDPtr, i, _$objects.pointer) + .object(const jni$_.JStringNullableType()); } - static final _id_sendOrderedBroadcastAsUser = _class.instanceMethodId( - r'sendOrderedBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_getSystemService = _class.instanceMethodId( + r'getSystemService', + r'(Ljava/lang/Class;)Ljava/lang/Object;', ); - static final _sendOrderedBroadcastAsUser = - jni$_.ProtectedJniExtensions.lookup< + static final _getSystemService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void sendOrderedBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, java.lang.String string, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle)` - void sendOrderedBroadcastAsUser( - jni$_.JObject? intent, - jni$_.JObject? userHandle, - jni$_.JString? string, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, - int i, - jni$_.JString? string1, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcastAsUser( - reference.pointer, - _id_sendOrderedBroadcastAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer, - _$string.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string1.pointer, - _$bundle.pointer) - .check(); + /// from: `public final T getSystemService(java.lang.Class class)` + /// The returned object must be released after use, by calling the [release] method. + $T? getSystemService<$T extends jni$_.JObject?>( + jni$_.JObject? class$, { + required jni$_.JObjType<$T> T, + }) { + final _$class$ = class$?.reference ?? jni$_.jNullReference; + return _getSystemService(reference.pointer, + _id_getSystemService as jni$_.JMethodIDPtr, _$class$.pointer) + .object<$T?>(T.nullableType); } - static final _id_sendOrderedBroadcast$4 = _class.instanceMethodId( - r'sendOrderedBroadcast', - r'(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_getSystemService$1 = _class.instanceMethodId( + r'getSystemService', + r'(Ljava/lang/String;)Ljava/lang/Object;', ); - static final _sendOrderedBroadcast$4 = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + static final _getSystemService$1 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); - - /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, java.lang.String string1, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string2, android.os.Bundle bundle)` - void sendOrderedBroadcast$4( - jni$_.JObject? intent, - jni$_.JString? string, - jni$_.JString? string1, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, - int i, - jni$_.JString? string2, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string2 = string2?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendOrderedBroadcast$4( - reference.pointer, - _id_sendOrderedBroadcast$4 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$string.pointer, - _$string1.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string2.pointer, - _$bundle.pointer) - .check(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); + + /// from: `public abstract java.lang.Object getSystemService(java.lang.String string)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getSystemService$1( + jni$_.JString? string, + ) { + final _$string = string?.reference ?? jni$_.jNullReference; + return _getSystemService$1(reference.pointer, + _id_getSystemService$1 as jni$_.JMethodIDPtr, _$string.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendStickyBroadcast = _class.instanceMethodId( - r'sendStickyBroadcast', - r'(Landroid/content/Intent;)V', + static final _id_getSystemServiceName = _class.instanceMethodId( + r'getSystemServiceName', + r'(Ljava/lang/Class;)Ljava/lang/String;', ); - static final _sendStickyBroadcast = jni$_.ProtectedJniExtensions.lookup< + static final _getSystemServiceName = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void sendStickyBroadcast(android.content.Intent intent)` - void sendStickyBroadcast( - jni$_.JObject? intent, + /// from: `public abstract java.lang.String getSystemServiceName(java.lang.Class class)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JString? getSystemServiceName( + jni$_.JObject? class$, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - _sendStickyBroadcast(reference.pointer, - _id_sendStickyBroadcast as jni$_.JMethodIDPtr, _$intent.pointer) - .check(); + final _$class$ = class$?.reference ?? jni$_.jNullReference; + return _getSystemServiceName(reference.pointer, + _id_getSystemServiceName as jni$_.JMethodIDPtr, _$class$.pointer) + .object(const jni$_.JStringNullableType()); } - static final _id_sendStickyBroadcast$1 = _class.instanceMethodId( - r'sendStickyBroadcast', - r'(Landroid/content/Intent;Landroid/os/Bundle;)V', + static final _id_getText = _class.instanceMethodId( + r'getText', + r'(I)Ljava/lang/CharSequence;', ); - static final _sendStickyBroadcast$1 = jni$_.ProtectedJniExtensions.lookup< + static final _getText = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public void sendStickyBroadcast(android.content.Intent intent, android.os.Bundle bundle)` - void sendStickyBroadcast$1( - jni$_.JObject? intent, - jni$_.JObject? bundle, + /// from: `public final java.lang.CharSequence getText(int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getText( + int i, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendStickyBroadcast$1( - reference.pointer, - _id_sendStickyBroadcast$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$bundle.pointer) - .check(); + return _getText(reference.pointer, _id_getText as jni$_.JMethodIDPtr, i) + .object(const jni$_.JObjectNullableType()); } - static final _id_sendStickyOrderedBroadcast = _class.instanceMethodId( - r'sendStickyOrderedBroadcast', - r'(Landroid/content/Intent;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_getTheme = _class.instanceMethodId( + r'getTheme', + r'()Landroid/content/res/Resources$Theme;', ); - static final _sendStickyOrderedBroadcast = + static final _getTheme = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public abstract android.content.res.Resources$Theme getTheme()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getTheme() { + return _getTheme(reference.pointer, _id_getTheme as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_getWallpaper = _class.instanceMethodId( + r'getWallpaper', + r'()Landroid/graphics/drawable/Drawable;', + ); + + static final _getWallpaper = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public abstract android.graphics.drawable.Drawable getWallpaper()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? getWallpaper() { + return _getWallpaper( + reference.pointer, _id_getWallpaper as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_getWallpaperDesiredMinimumHeight = _class.instanceMethodId( + r'getWallpaperDesiredMinimumHeight', + r'()I', + ); + + static final _getWallpaperDesiredMinimumHeight = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallIntMethod') .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendStickyOrderedBroadcast(android.content.Intent intent, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string, android.os.Bundle bundle)` - void sendStickyOrderedBroadcast( - jni$_.JObject? intent, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, - int i, - jni$_.JString? string, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendStickyOrderedBroadcast( - reference.pointer, - _id_sendStickyOrderedBroadcast as jni$_.JMethodIDPtr, - _$intent.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract int getWallpaperDesiredMinimumHeight()` + int getWallpaperDesiredMinimumHeight() { + return _getWallpaperDesiredMinimumHeight(reference.pointer, + _id_getWallpaperDesiredMinimumHeight as jni$_.JMethodIDPtr) + .integer; } - static final _id_removeStickyBroadcast = _class.instanceMethodId( - r'removeStickyBroadcast', - r'(Landroid/content/Intent;)V', + static final _id_getWallpaperDesiredMinimumWidth = _class.instanceMethodId( + r'getWallpaperDesiredMinimumWidth', + r'()I', ); - static final _removeStickyBroadcast = jni$_.ProtectedJniExtensions.lookup< + static final _getWallpaperDesiredMinimumWidth = + 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)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallIntMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void removeStickyBroadcast(android.content.Intent intent)` - void removeStickyBroadcast( - jni$_.JObject? intent, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - _removeStickyBroadcast(reference.pointer, - _id_removeStickyBroadcast as jni$_.JMethodIDPtr, _$intent.pointer) - .check(); + /// from: `public abstract int getWallpaperDesiredMinimumWidth()` + int getWallpaperDesiredMinimumWidth() { + return _getWallpaperDesiredMinimumWidth(reference.pointer, + _id_getWallpaperDesiredMinimumWidth as jni$_.JMethodIDPtr) + .integer; } - static final _id_sendStickyBroadcastAsUser = _class.instanceMethodId( - r'sendStickyBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', + static final _id_grantUriPermission = _class.instanceMethodId( + r'grantUriPermission', + r'(Ljava/lang/String;Landroid/net/Uri;I)V', ); - static final _sendStickyBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< + static final _grantUriPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -45991,137 +46224,112 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer + jni$_.Pointer, + jni$_.Int32 )>)>>('globalEnv_CallVoidMethod') .asFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + int)>(); - /// from: `public abstract void sendStickyBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` - void sendStickyBroadcastAsUser( - jni$_.JObject? intent, - jni$_.JObject? userHandle, + /// from: `public abstract void grantUriPermission(java.lang.String string, android.net.Uri uri, int i)` + void grantUriPermission( + jni$_.JString? string, + jni$_.JObject? uri, + int i, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - _sendStickyBroadcastAsUser( + final _$string = string?.reference ?? jni$_.jNullReference; + final _$uri = uri?.reference ?? jni$_.jNullReference; + _grantUriPermission( reference.pointer, - _id_sendStickyBroadcastAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer) + _id_grantUriPermission as jni$_.JMethodIDPtr, + _$string.pointer, + _$uri.pointer, + i) .check(); } - static final _id_sendStickyOrderedBroadcastAsUser = _class.instanceMethodId( - r'sendStickyOrderedBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', + static final _id_isDeviceProtectedStorage = _class.instanceMethodId( + r'isDeviceProtectedStorage', + r'()Z', ); - static final _sendStickyOrderedBroadcastAsUser = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer)>(); + static final _isDeviceProtectedStorage = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void sendStickyOrderedBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string, android.os.Bundle bundle)` - void sendStickyOrderedBroadcastAsUser( - jni$_.JObject? intent, - jni$_.JObject? userHandle, - jni$_.JObject? broadcastReceiver, - jni$_.JObject? handler, - int i, - jni$_.JString? string, - jni$_.JObject? bundle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - _sendStickyOrderedBroadcastAsUser( - reference.pointer, - _id_sendStickyOrderedBroadcastAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer, - _$broadcastReceiver.pointer, - _$handler.pointer, - i, - _$string.pointer, - _$bundle.pointer) - .check(); + /// from: `public abstract boolean isDeviceProtectedStorage()` + bool isDeviceProtectedStorage() { + return _isDeviceProtectedStorage(reference.pointer, + _id_isDeviceProtectedStorage as jni$_.JMethodIDPtr) + .boolean; } - static final _id_removeStickyBroadcastAsUser = _class.instanceMethodId( - r'removeStickyBroadcastAsUser', - r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', + static final _id_isRestricted = _class.instanceMethodId( + r'isRestricted', + r'()Z', ); - static final _removeStickyBroadcastAsUser = - 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)>(); + static final _isRestricted = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public abstract void removeStickyBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` - void removeStickyBroadcastAsUser( - jni$_.JObject? intent, - jni$_.JObject? userHandle, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - _removeStickyBroadcastAsUser( - reference.pointer, - _id_removeStickyBroadcastAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$userHandle.pointer) - .check(); + /// from: `public boolean isRestricted()` + bool isRestricted() { + return _isRestricted( + reference.pointer, _id_isRestricted as jni$_.JMethodIDPtr) + .boolean; } - static final _id_registerReceiver = _class.instanceMethodId( - r'registerReceiver', - r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;', + static final _id_isUiContext = _class.instanceMethodId( + r'isUiContext', + r'()Z', ); - static final _registerReceiver = jni$_.ProtectedJniExtensions.lookup< + static final _isUiContext = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallBooleanMethod') + .asFunction< + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); + + /// from: `public boolean isUiContext()` + bool isUiContext() { + return _isUiContext( + reference.pointer, _id_isUiContext as jni$_.JMethodIDPtr) + .boolean; + } + + static final _id_moveDatabaseFrom = _class.instanceMethodId( + r'moveDatabaseFrom', + r'(Landroid/content/Context;Ljava/lang/String;)Z', + ); + + static final _moveDatabaseFrom = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46130,7 +46338,7 @@ class Context extends jni$_.JObject { ( jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46138,29 +46346,27 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? registerReceiver( - jni$_.JObject? broadcastReceiver, - jni$_.JObject? intentFilter, + /// from: `public abstract boolean moveDatabaseFrom(android.content.Context context, java.lang.String string)` + bool moveDatabaseFrom( + Context? context, + jni$_.JString? string, ) { - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; - return _registerReceiver( + final _$context = context?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + return _moveDatabaseFrom( reference.pointer, - _id_registerReceiver as jni$_.JMethodIDPtr, - _$broadcastReceiver.pointer, - _$intentFilter.pointer) - .object(const jni$_.JObjectNullableType()); + _id_moveDatabaseFrom as jni$_.JMethodIDPtr, + _$context.pointer, + _$string.pointer) + .boolean; } - static final _id_registerReceiver$1 = _class.instanceMethodId( - r'registerReceiver', - r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent;', + static final _id_moveSharedPreferencesFrom = _class.instanceMethodId( + r'moveSharedPreferencesFrom', + r'(Landroid/content/Context;Ljava/lang/String;)Z', ); - static final _registerReceiver$1 = jni$_.ProtectedJniExtensions.lookup< + static final _moveSharedPreferencesFrom = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46168,50 +46374,42 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32 - )>)>>('globalEnv_CallObjectMethod') + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, - int)>(); + jni$_.Pointer)>(); - /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? registerReceiver$1( - jni$_.JObject? broadcastReceiver, - jni$_.JObject? intentFilter, - int i, + /// from: `public abstract boolean moveSharedPreferencesFrom(android.content.Context context, java.lang.String string)` + bool moveSharedPreferencesFrom( + Context? context, + jni$_.JString? string, ) { - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; - return _registerReceiver$1( + final _$context = context?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + return _moveSharedPreferencesFrom( reference.pointer, - _id_registerReceiver$1 as jni$_.JMethodIDPtr, - _$broadcastReceiver.pointer, - _$intentFilter.pointer, - i) - .object(const jni$_.JObjectNullableType()); + _id_moveSharedPreferencesFrom as jni$_.JMethodIDPtr, + _$context.pointer, + _$string.pointer) + .boolean; } - static final _id_registerReceiver$2 = _class.instanceMethodId( - r'registerReceiver', - r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;)Landroid/content/Intent;', + static final _id_obtainStyledAttributes = _class.instanceMethodId( + r'obtainStyledAttributes', + r'(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;', ); - static final _registerReceiver$2 = jni$_.ProtectedJniExtensions.lookup< + static final _obtainStyledAttributes = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, - jni$_.Pointer, jni$_.Pointer, jni$_.Pointer )>)>>('globalEnv_CallObjectMethod') @@ -46220,39 +46418,30 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, java.lang.String string, android.os.Handler handler)` + /// from: `public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet attributeSet, int[] is)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? registerReceiver$2( - jni$_.JObject? broadcastReceiver, - jni$_.JObject? intentFilter, - jni$_.JString? string, - jni$_.JObject? handler, + jni$_.JObject? obtainStyledAttributes( + jni$_.JObject? attributeSet, + jni$_.JIntArray? is$, ) { - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - return _registerReceiver$2( + final _$attributeSet = attributeSet?.reference ?? jni$_.jNullReference; + final _$is$ = is$?.reference ?? jni$_.jNullReference; + return _obtainStyledAttributes( reference.pointer, - _id_registerReceiver$2 as jni$_.JMethodIDPtr, - _$broadcastReceiver.pointer, - _$intentFilter.pointer, - _$string.pointer, - _$handler.pointer) + _id_obtainStyledAttributes as jni$_.JMethodIDPtr, + _$attributeSet.pointer, + _$is$.pointer) .object(const jni$_.JObjectNullableType()); } - static final _id_registerReceiver$3 = _class.instanceMethodId( - r'registerReceiver', - r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;I)Landroid/content/Intent;', + static final _id_obtainStyledAttributes$1 = _class.instanceMethodId( + r'obtainStyledAttributes', + r'(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;', ); - static final _registerReceiver$3 = jni$_.ProtectedJniExtensions.lookup< + static final _obtainStyledAttributes$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46261,8 +46450,7 @@ class Context extends jni$_.JObject { ( jni$_.Pointer, jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, + jni$_.Int32, jni$_.Int32 )>)>>('globalEnv_CallObjectMethod') .asFunction< @@ -46271,70 +46459,67 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.Pointer, jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, + int, int)>(); - /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, java.lang.String string, android.os.Handler handler, int i)` + /// from: `public final android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet attributeSet, int[] is, int i, int i1)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? registerReceiver$3( - jni$_.JObject? broadcastReceiver, - jni$_.JObject? intentFilter, - jni$_.JString? string, - jni$_.JObject? handler, + jni$_.JObject? obtainStyledAttributes$1( + jni$_.JObject? attributeSet, + jni$_.JIntArray? is$, int i, + int i1, ) { - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$handler = handler?.reference ?? jni$_.jNullReference; - return _registerReceiver$3( + final _$attributeSet = attributeSet?.reference ?? jni$_.jNullReference; + final _$is$ = is$?.reference ?? jni$_.jNullReference; + return _obtainStyledAttributes$1( reference.pointer, - _id_registerReceiver$3 as jni$_.JMethodIDPtr, - _$broadcastReceiver.pointer, - _$intentFilter.pointer, - _$string.pointer, - _$handler.pointer, - i) + _id_obtainStyledAttributes$1 as jni$_.JMethodIDPtr, + _$attributeSet.pointer, + _$is$.pointer, + i, + i1) .object(const jni$_.JObjectNullableType()); } - static final _id_unregisterReceiver = _class.instanceMethodId( - r'unregisterReceiver', - r'(Landroid/content/BroadcastReceiver;)V', + static final _id_obtainStyledAttributes$2 = _class.instanceMethodId( + r'obtainStyledAttributes', + r'(I[I)Landroid/content/res/TypedArray;', ); - static final _unregisterReceiver = jni$_.ProtectedJniExtensions.lookup< + static final _obtainStyledAttributes$2 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallVoidMethod') + jni$_ + .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JniResult Function(jni$_.Pointer, + jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); - /// from: `public abstract void unregisterReceiver(android.content.BroadcastReceiver broadcastReceiver)` - void unregisterReceiver( - jni$_.JObject? broadcastReceiver, + /// from: `public final android.content.res.TypedArray obtainStyledAttributes(int i, int[] is)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? obtainStyledAttributes$2( + int i, + jni$_.JIntArray? is$, ) { - final _$broadcastReceiver = - broadcastReceiver?.reference ?? jni$_.jNullReference; - _unregisterReceiver( + final _$is$ = is$?.reference ?? jni$_.jNullReference; + return _obtainStyledAttributes$2( reference.pointer, - _id_unregisterReceiver as jni$_.JMethodIDPtr, - _$broadcastReceiver.pointer) - .check(); + _id_obtainStyledAttributes$2 as jni$_.JMethodIDPtr, + i, + _$is$.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_startService = _class.instanceMethodId( - r'startService', - r'(Landroid/content/Intent;)Landroid/content/ComponentName;', + static final _id_obtainStyledAttributes$3 = _class.instanceMethodId( + r'obtainStyledAttributes', + r'([I)Landroid/content/res/TypedArray;', ); - static final _startService = jni$_.ProtectedJniExtensions.lookup< + static final _obtainStyledAttributes$3 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46345,23 +46530,23 @@ class Context extends jni$_.JObject { jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract android.content.ComponentName startService(android.content.Intent intent)` + /// from: `public final android.content.res.TypedArray obtainStyledAttributes(int[] is)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? startService( - jni$_.JObject? intent, + jni$_.JObject? obtainStyledAttributes$3( + jni$_.JIntArray? is$, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - return _startService(reference.pointer, - _id_startService as jni$_.JMethodIDPtr, _$intent.pointer) + final _$is$ = is$?.reference ?? jni$_.jNullReference; + return _obtainStyledAttributes$3(reference.pointer, + _id_obtainStyledAttributes$3 as jni$_.JMethodIDPtr, _$is$.pointer) .object(const jni$_.JObjectNullableType()); } - static final _id_startForegroundService = _class.instanceMethodId( - r'startForegroundService', - r'(Landroid/content/Intent;)Landroid/content/ComponentName;', + static final _id_openFileInput = _class.instanceMethodId( + r'openFileInput', + r'(Ljava/lang/String;)Ljava/io/FileInputStream;', ); - static final _startForegroundService = jni$_.ProtectedJniExtensions.lookup< + static final _openFileInput = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46372,91 +46557,52 @@ class Context extends jni$_.JObject { jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract android.content.ComponentName startForegroundService(android.content.Intent intent)` + /// from: `public abstract java.io.FileInputStream openFileInput(java.lang.String string)` /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? startForegroundService( - jni$_.JObject? intent, + jni$_.JObject? openFileInput( + jni$_.JString? string, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - return _startForegroundService(reference.pointer, - _id_startForegroundService as jni$_.JMethodIDPtr, _$intent.pointer) + final _$string = string?.reference ?? jni$_.jNullReference; + return _openFileInput(reference.pointer, + _id_openFileInput as jni$_.JMethodIDPtr, _$string.pointer) .object(const jni$_.JObjectNullableType()); } - static final _id_stopService = _class.instanceMethodId( - r'stopService', - r'(Landroid/content/Intent;)Z', + static final _id_openFileOutput = _class.instanceMethodId( + r'openFileOutput', + r'(Ljava/lang/String;I)Ljava/io/FileOutputStream;', ); - static final _stopService = jni$_.ProtectedJniExtensions.lookup< + static final _openFileOutput = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallBooleanMethod') + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); - - /// from: `public abstract boolean stopService(android.content.Intent intent)` - bool stopService( - jni$_.JObject? intent, - ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - return _stopService(reference.pointer, - _id_stopService as jni$_.JMethodIDPtr, _$intent.pointer) - .boolean; - } - - static final _id_bindService = _class.instanceMethodId( - r'bindService', - r'(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z', - ); - - static final _bindService = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32 - )>)>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - int)>(); + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public abstract boolean bindService(android.content.Intent intent, android.content.ServiceConnection serviceConnection, int i)` - bool bindService( - jni$_.JObject? intent, - jni$_.JObject? serviceConnection, + /// from: `public abstract java.io.FileOutputStream openFileOutput(java.lang.String string, int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? openFileOutput( + jni$_.JString? string, int i, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - return _bindService( - reference.pointer, - _id_bindService as jni$_.JMethodIDPtr, - _$intent.pointer, - _$serviceConnection.pointer, - i) - .boolean; + final _$string = string?.reference ?? jni$_.jNullReference; + return _openFileOutput(reference.pointer, + _id_openFileOutput as jni$_.JMethodIDPtr, _$string.pointer, i) + .object(const jni$_.JObjectNullableType()); } - static final _id_bindService$1 = _class.instanceMethodId( - r'bindService', - r'(Landroid/content/Intent;Landroid/content/ServiceConnection;Landroid/content/Context$BindServiceFlags;)Z', + static final _id_openOrCreateDatabase = _class.instanceMethodId( + r'openOrCreateDatabase', + r'(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;)Landroid/database/sqlite/SQLiteDatabase;', ); - static final _bindService$1 = jni$_.ProtectedJniExtensions.lookup< + static final _openOrCreateDatabase = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46464,43 +46610,41 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer, + jni$_.Int32, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, + int, jni$_.Pointer)>(); - /// from: `public boolean bindService(android.content.Intent intent, android.content.ServiceConnection serviceConnection, android.content.Context$BindServiceFlags bindServiceFlags)` - bool bindService$1( - jni$_.JObject? intent, - jni$_.JObject? serviceConnection, - Context$BindServiceFlags? bindServiceFlags, + /// from: `public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String string, int i, android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? openOrCreateDatabase( + jni$_.JString? string, + int i, + jni$_.JObject? cursorFactory, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - final _$bindServiceFlags = - bindServiceFlags?.reference ?? jni$_.jNullReference; - return _bindService$1( + final _$string = string?.reference ?? jni$_.jNullReference; + final _$cursorFactory = cursorFactory?.reference ?? jni$_.jNullReference; + return _openOrCreateDatabase( reference.pointer, - _id_bindService$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$serviceConnection.pointer, - _$bindServiceFlags.pointer) - .boolean; + _id_openOrCreateDatabase as jni$_.JMethodIDPtr, + _$string.pointer, + i, + _$cursorFactory.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_bindService$2 = _class.instanceMethodId( - r'bindService', - r'(Landroid/content/Intent;ILjava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', + static final _id_openOrCreateDatabase$1 = _class.instanceMethodId( + r'openOrCreateDatabase', + r'(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;)Landroid/database/sqlite/SQLiteDatabase;', ); - static final _bindService$2 = jni$_.ProtectedJniExtensions.lookup< + static final _openOrCreateDatabase$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46511,7 +46655,7 @@ class Context extends jni$_.JObject { jni$_.Int32, jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46521,188 +46665,166 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public boolean bindService(android.content.Intent intent, int i, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` - bool bindService$2( - jni$_.JObject? intent, + /// from: `public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String string, int i, android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, android.database.DatabaseErrorHandler databaseErrorHandler)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? openOrCreateDatabase$1( + jni$_.JString? string, int i, - jni$_.JObject? executor, - jni$_.JObject? serviceConnection, + jni$_.JObject? cursorFactory, + jni$_.JObject? databaseErrorHandler, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$executor = executor?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - return _bindService$2( + final _$string = string?.reference ?? jni$_.jNullReference; + final _$cursorFactory = cursorFactory?.reference ?? jni$_.jNullReference; + final _$databaseErrorHandler = + databaseErrorHandler?.reference ?? jni$_.jNullReference; + return _openOrCreateDatabase$1( reference.pointer, - _id_bindService$2 as jni$_.JMethodIDPtr, - _$intent.pointer, + _id_openOrCreateDatabase$1 as jni$_.JMethodIDPtr, + _$string.pointer, i, - _$executor.pointer, - _$serviceConnection.pointer) - .boolean; + _$cursorFactory.pointer, + _$databaseErrorHandler.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_bindService$3 = _class.instanceMethodId( - r'bindService', - r'(Landroid/content/Intent;Landroid/content/Context$BindServiceFlags;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', + static final _id_peekWallpaper = _class.instanceMethodId( + r'peekWallpaper', + r'()Landroid/graphics/drawable/Drawable;', ); - static final _bindService$3 = jni$_.ProtectedJniExtensions.lookup< + static final _peekWallpaper = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + )>(); - /// from: `public boolean bindService(android.content.Intent intent, android.content.Context$BindServiceFlags bindServiceFlags, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` - bool bindService$3( - jni$_.JObject? intent, - Context$BindServiceFlags? bindServiceFlags, - jni$_.JObject? executor, - jni$_.JObject? serviceConnection, + /// from: `public abstract android.graphics.drawable.Drawable peekWallpaper()` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? peekWallpaper() { + return _peekWallpaper( + reference.pointer, _id_peekWallpaper as jni$_.JMethodIDPtr) + .object(const jni$_.JObjectNullableType()); + } + + static final _id_registerComponentCallbacks = _class.instanceMethodId( + r'registerComponentCallbacks', + r'(Landroid/content/ComponentCallbacks;)V', + ); + + static final _registerComponentCallbacks = + 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 registerComponentCallbacks(android.content.ComponentCallbacks componentCallbacks)` + void registerComponentCallbacks( + jni$_.JObject? componentCallbacks, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$bindServiceFlags = - bindServiceFlags?.reference ?? jni$_.jNullReference; - final _$executor = executor?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - return _bindService$3( + final _$componentCallbacks = + componentCallbacks?.reference ?? jni$_.jNullReference; + _registerComponentCallbacks( reference.pointer, - _id_bindService$3 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$bindServiceFlags.pointer, - _$executor.pointer, - _$serviceConnection.pointer) - .boolean; + _id_registerComponentCallbacks as jni$_.JMethodIDPtr, + _$componentCallbacks.pointer) + .check(); } - static final _id_bindIsolatedService = _class.instanceMethodId( - r'bindIsolatedService', - r'(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', + static final _id_registerDeviceIdChangeListener = _class.instanceMethodId( + r'registerDeviceIdChangeListener', + r'(Ljava/util/concurrent/Executor;Ljava/util/function/IntConsumer;)V', ); - static final _bindIsolatedService = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( + static final _registerDeviceIdChangeListener = + 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$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public boolean bindIsolatedService(android.content.Intent intent, int i, java.lang.String string, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` - bool bindIsolatedService( - jni$_.JObject? intent, - int i, - jni$_.JString? string, + /// from: `public void registerDeviceIdChangeListener(java.util.concurrent.Executor executor, java.util.function.IntConsumer intConsumer)` + void registerDeviceIdChangeListener( jni$_.JObject? executor, - jni$_.JObject? serviceConnection, + jni$_.JObject? intConsumer, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; final _$executor = executor?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - return _bindIsolatedService( + final _$intConsumer = intConsumer?.reference ?? jni$_.jNullReference; + _registerDeviceIdChangeListener( reference.pointer, - _id_bindIsolatedService as jni$_.JMethodIDPtr, - _$intent.pointer, - i, - _$string.pointer, + _id_registerDeviceIdChangeListener as jni$_.JMethodIDPtr, _$executor.pointer, - _$serviceConnection.pointer) - .boolean; + _$intConsumer.pointer) + .check(); } - static final _id_bindIsolatedService$1 = _class.instanceMethodId( - r'bindIsolatedService', - r'(Landroid/content/Intent;Landroid/content/Context$BindServiceFlags;Ljava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z', + static final _id_registerReceiver = _class.instanceMethodId( + r'registerReceiver', + r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;', ); - static final _bindIsolatedService$1 = jni$_.ProtectedJniExtensions.lookup< + static final _registerReceiver = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public boolean bindIsolatedService(android.content.Intent intent, android.content.Context$BindServiceFlags bindServiceFlags, java.lang.String string, java.util.concurrent.Executor executor, android.content.ServiceConnection serviceConnection)` - bool bindIsolatedService$1( - jni$_.JObject? intent, - Context$BindServiceFlags? bindServiceFlags, - jni$_.JString? string, - jni$_.JObject? executor, - jni$_.JObject? serviceConnection, + /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? registerReceiver( + jni$_.JObject? broadcastReceiver, + jni$_.JObject? intentFilter, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$bindServiceFlags = - bindServiceFlags?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$executor = executor?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - return _bindIsolatedService$1( + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; + return _registerReceiver( reference.pointer, - _id_bindIsolatedService$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$bindServiceFlags.pointer, - _$string.pointer, - _$executor.pointer, - _$serviceConnection.pointer) - .boolean; + _id_registerReceiver as jni$_.JMethodIDPtr, + _$broadcastReceiver.pointer, + _$intentFilter.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_bindServiceAsUser = _class.instanceMethodId( - r'bindServiceAsUser', - r'(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/UserHandle;)Z', + static final _id_registerReceiver$1 = _class.instanceMethodId( + r'registerReceiver', + r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent;', ); - static final _bindServiceAsUser = jni$_.ProtectedJniExtensions.lookup< + static final _registerReceiver$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46711,45 +46833,41 @@ class Context extends jni$_.JObject { ( jni$_.Pointer, jni$_.Pointer, - jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + jni$_.Int32 + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, jni$_.Pointer, - int, - jni$_.Pointer)>(); + int)>(); - /// from: `public boolean bindServiceAsUser(android.content.Intent intent, android.content.ServiceConnection serviceConnection, int i, android.os.UserHandle userHandle)` - bool bindServiceAsUser( - jni$_.JObject? intent, - jni$_.JObject? serviceConnection, + /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? registerReceiver$1( + jni$_.JObject? broadcastReceiver, + jni$_.JObject? intentFilter, int i, - jni$_.JObject? userHandle, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - return _bindServiceAsUser( + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; + return _registerReceiver$1( reference.pointer, - _id_bindServiceAsUser as jni$_.JMethodIDPtr, - _$intent.pointer, - _$serviceConnection.pointer, - i, - _$userHandle.pointer) - .boolean; + _id_registerReceiver$1 as jni$_.JMethodIDPtr, + _$broadcastReceiver.pointer, + _$intentFilter.pointer, + i) + .object(const jni$_.JObjectNullableType()); } - static final _id_bindServiceAsUser$1 = _class.instanceMethodId( - r'bindServiceAsUser', - r'(Landroid/content/Intent;Landroid/content/ServiceConnection;Landroid/content/Context$BindServiceFlags;Landroid/os/UserHandle;)Z', + static final _id_registerReceiver$2 = _class.instanceMethodId( + r'registerReceiver', + r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;)Landroid/content/Intent;', ); - static final _bindServiceAsUser$1 = jni$_.ProtectedJniExtensions.lookup< + static final _registerReceiver$2 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46760,7 +46878,7 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.Pointer, jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -46770,72 +46888,88 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public boolean bindServiceAsUser(android.content.Intent intent, android.content.ServiceConnection serviceConnection, android.content.Context$BindServiceFlags bindServiceFlags, android.os.UserHandle userHandle)` - bool bindServiceAsUser$1( - jni$_.JObject? intent, - jni$_.JObject? serviceConnection, - Context$BindServiceFlags? bindServiceFlags, - jni$_.JObject? userHandle, + /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, java.lang.String string, android.os.Handler handler)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? registerReceiver$2( + jni$_.JObject? broadcastReceiver, + jni$_.JObject? intentFilter, + jni$_.JString? string, + jni$_.JObject? handler, ) { - final _$intent = intent?.reference ?? jni$_.jNullReference; - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - final _$bindServiceFlags = - bindServiceFlags?.reference ?? jni$_.jNullReference; - final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; - return _bindServiceAsUser$1( + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + return _registerReceiver$2( reference.pointer, - _id_bindServiceAsUser$1 as jni$_.JMethodIDPtr, - _$intent.pointer, - _$serviceConnection.pointer, - _$bindServiceFlags.pointer, - _$userHandle.pointer) - .boolean; + _id_registerReceiver$2 as jni$_.JMethodIDPtr, + _$broadcastReceiver.pointer, + _$intentFilter.pointer, + _$string.pointer, + _$handler.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_updateServiceGroup = _class.instanceMethodId( - r'updateServiceGroup', - r'(Landroid/content/ServiceConnection;II)V', + static final _id_registerReceiver$3 = _class.instanceMethodId( + r'registerReceiver', + r'(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;I)Landroid/content/Intent;', ); - static final _updateServiceGroup = jni$_.ProtectedJniExtensions.lookup< + static final _registerReceiver$3 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JThrowablePtr Function( + jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, jni$_.Int32 - )>)>>('globalEnv_CallVoidMethod') + )>)>>('globalEnv_CallObjectMethod') .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int, int)>(); + jni$_.JniResult Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + int)>(); - /// from: `public void updateServiceGroup(android.content.ServiceConnection serviceConnection, int i, int i1)` - void updateServiceGroup( - jni$_.JObject? serviceConnection, + /// from: `public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver broadcastReceiver, android.content.IntentFilter intentFilter, java.lang.String string, android.os.Handler handler, int i)` + /// The returned object must be released after use, by calling the [release] method. + jni$_.JObject? registerReceiver$3( + jni$_.JObject? broadcastReceiver, + jni$_.JObject? intentFilter, + jni$_.JString? string, + jni$_.JObject? handler, int i, - int i1, ) { - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - _updateServiceGroup( + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$intentFilter = intentFilter?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + return _registerReceiver$3( reference.pointer, - _id_updateServiceGroup as jni$_.JMethodIDPtr, - _$serviceConnection.pointer, - i, - i1) - .check(); + _id_registerReceiver$3 as jni$_.JMethodIDPtr, + _$broadcastReceiver.pointer, + _$intentFilter.pointer, + _$string.pointer, + _$handler.pointer, + i) + .object(const jni$_.JObjectNullableType()); } - static final _id_unbindService = _class.instanceMethodId( - r'unbindService', - r'(Landroid/content/ServiceConnection;)V', + static final _id_removeStickyBroadcast = _class.instanceMethodId( + r'removeStickyBroadcast', + r'(Landroid/content/Intent;)V', ); - static final _unbindService = jni$_.ProtectedJniExtensions.lookup< + static final _removeStickyBroadcast = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -46846,260 +46980,292 @@ class Context extends jni$_.JObject { jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract void unbindService(android.content.ServiceConnection serviceConnection)` - void unbindService( - jni$_.JObject? serviceConnection, + /// from: `public abstract void removeStickyBroadcast(android.content.Intent intent)` + void removeStickyBroadcast( + jni$_.JObject? intent, ) { - final _$serviceConnection = - serviceConnection?.reference ?? jni$_.jNullReference; - _unbindService(reference.pointer, _id_unbindService as jni$_.JMethodIDPtr, - _$serviceConnection.pointer) + final _$intent = intent?.reference ?? jni$_.jNullReference; + _removeStickyBroadcast(reference.pointer, + _id_removeStickyBroadcast as jni$_.JMethodIDPtr, _$intent.pointer) .check(); } - static final _id_startInstrumentation = _class.instanceMethodId( - r'startInstrumentation', - r'(Landroid/content/ComponentName;Ljava/lang/String;Landroid/os/Bundle;)Z', + static final _id_removeStickyBroadcastAsUser = _class.instanceMethodId( + r'removeStickyBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', ); - static final _startInstrumentation = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( + static final _removeStickyBroadcastAsUser = + 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$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer)>(); + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract boolean startInstrumentation(android.content.ComponentName componentName, java.lang.String string, android.os.Bundle bundle)` - bool startInstrumentation( - jni$_.JObject? componentName, - jni$_.JString? string, - jni$_.JObject? bundle, + /// from: `public abstract void removeStickyBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` + void removeStickyBroadcastAsUser( + jni$_.JObject? intent, + jni$_.JObject? userHandle, ) { - final _$componentName = componentName?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - return _startInstrumentation( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + _removeStickyBroadcastAsUser( reference.pointer, - _id_startInstrumentation as jni$_.JMethodIDPtr, - _$componentName.pointer, - _$string.pointer, - _$bundle.pointer) - .boolean; + _id_removeStickyBroadcastAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer) + .check(); } - static final _id_getSystemService = _class.instanceMethodId( - r'getSystemService', - r'(Ljava/lang/String;)Ljava/lang/Object;', + static final _id_revokeSelfPermissionOnKill = _class.instanceMethodId( + r'revokeSelfPermissionOnKill', + r'(Ljava/lang/String;)V', ); - static final _getSystemService = 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)>(); + static final _revokeSelfPermissionOnKill = + 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 java.lang.Object getSystemService(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getSystemService( + /// from: `public void revokeSelfPermissionOnKill(java.lang.String string)` + void revokeSelfPermissionOnKill( jni$_.JString? string, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _getSystemService(reference.pointer, - _id_getSystemService as jni$_.JMethodIDPtr, _$string.pointer) - .object(const jni$_.JObjectNullableType()); + _revokeSelfPermissionOnKill( + reference.pointer, + _id_revokeSelfPermissionOnKill as jni$_.JMethodIDPtr, + _$string.pointer) + .check(); } - static final _id_getSystemService$1 = _class.instanceMethodId( - r'getSystemService', - r'(Ljava/lang/Class;)Ljava/lang/Object;', + static final _id_revokeSelfPermissionsOnKill = _class.instanceMethodId( + r'revokeSelfPermissionsOnKill', + r'(Ljava/util/Collection;)V', ); - static final _getSystemService$1 = 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)>(); + static final _revokeSelfPermissionsOnKill = + 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 final T getSystemService(java.lang.Class class)` - /// The returned object must be released after use, by calling the [release] method. - $T? getSystemService$1<$T extends jni$_.JObject?>( - jni$_.JObject? class$, { - required jni$_.JObjType<$T> T, - }) { - final _$class$ = class$?.reference ?? jni$_.jNullReference; - return _getSystemService$1(reference.pointer, - _id_getSystemService$1 as jni$_.JMethodIDPtr, _$class$.pointer) - .object<$T?>(T.nullableType); + /// from: `public void revokeSelfPermissionsOnKill(java.util.Collection collection)` + void revokeSelfPermissionsOnKill( + jni$_.JObject? collection, + ) { + final _$collection = collection?.reference ?? jni$_.jNullReference; + _revokeSelfPermissionsOnKill( + reference.pointer, + _id_revokeSelfPermissionsOnKill as jni$_.JMethodIDPtr, + _$collection.pointer) + .check(); } - static final _id_getSystemServiceName = _class.instanceMethodId( - r'getSystemServiceName', - r'(Ljava/lang/Class;)Ljava/lang/String;', + static final _id_revokeUriPermission = _class.instanceMethodId( + r'revokeUriPermission', + r'(Landroid/net/Uri;I)V', ); - static final _getSystemServiceName = jni$_.ProtectedJniExtensions.lookup< + static final _revokeUriPermission = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + jni$_ + .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - /// from: `public abstract java.lang.String getSystemServiceName(java.lang.Class class)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JString? getSystemServiceName( - jni$_.JObject? class$, + /// from: `public abstract void revokeUriPermission(android.net.Uri uri, int i)` + void revokeUriPermission( + jni$_.JObject? uri, + int i, ) { - final _$class$ = class$?.reference ?? jni$_.jNullReference; - return _getSystemServiceName(reference.pointer, - _id_getSystemServiceName as jni$_.JMethodIDPtr, _$class$.pointer) - .object(const jni$_.JStringNullableType()); + final _$uri = uri?.reference ?? jni$_.jNullReference; + _revokeUriPermission(reference.pointer, + _id_revokeUriPermission as jni$_.JMethodIDPtr, _$uri.pointer, i) + .check(); } - static final _id_checkPermission = _class.instanceMethodId( - r'checkPermission', - r'(Ljava/lang/String;II)I', + static final _id_revokeUriPermission$1 = _class.instanceMethodId( + r'revokeUriPermission', + r'(Ljava/lang/String;Landroid/net/Uri;I)V', ); - static final _checkPermission = jni$_.ProtectedJniExtensions.lookup< + static final _revokeUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, + jni$_.Pointer, jni$_.Int32 - )>)>>('globalEnv_CallIntMethod') + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int, int)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + int)>(); - /// from: `public abstract int checkPermission(java.lang.String string, int i, int i1)` - int checkPermission( + /// from: `public abstract void revokeUriPermission(java.lang.String string, android.net.Uri uri, int i)` + void revokeUriPermission$1( jni$_.JString? string, + jni$_.JObject? uri, int i, - int i1, ) { final _$string = string?.reference ?? jni$_.jNullReference; - return _checkPermission(reference.pointer, - _id_checkPermission as jni$_.JMethodIDPtr, _$string.pointer, i, i1) - .integer; + final _$uri = uri?.reference ?? jni$_.jNullReference; + _revokeUriPermission$1( + reference.pointer, + _id_revokeUriPermission$1 as jni$_.JMethodIDPtr, + _$string.pointer, + _$uri.pointer, + i) + .check(); } - static final _id_checkCallingPermission = _class.instanceMethodId( - r'checkCallingPermission', - r'(Ljava/lang/String;)I', + static final _id_sendBroadcast = _class.instanceMethodId( + r'sendBroadcast', + r'(Landroid/content/Intent;)V', ); - static final _checkCallingPermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendBroadcast = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, + jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract int checkCallingPermission(java.lang.String string)` - int checkCallingPermission( - jni$_.JString? string, + /// from: `public abstract void sendBroadcast(android.content.Intent intent)` + void sendBroadcast( + jni$_.JObject? intent, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _checkCallingPermission(reference.pointer, - _id_checkCallingPermission as jni$_.JMethodIDPtr, _$string.pointer) - .integer; + final _$intent = intent?.reference ?? jni$_.jNullReference; + _sendBroadcast(reference.pointer, _id_sendBroadcast as jni$_.JMethodIDPtr, + _$intent.pointer) + .check(); } - static final _id_checkCallingOrSelfPermission = _class.instanceMethodId( - r'checkCallingOrSelfPermission', - r'(Ljava/lang/String;)I', + static final _id_sendBroadcast$1 = _class.instanceMethodId( + r'sendBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;)V', ); - static final _checkCallingOrSelfPermission = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + static final _sendBroadcast$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 abstract int checkCallingOrSelfPermission(java.lang.String string)` - int checkCallingOrSelfPermission( + /// from: `public abstract void sendBroadcast(android.content.Intent intent, java.lang.String string)` + void sendBroadcast$1( + jni$_.JObject? intent, jni$_.JString? string, ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - return _checkCallingOrSelfPermission( + _sendBroadcast$1( reference.pointer, - _id_checkCallingOrSelfPermission as jni$_.JMethodIDPtr, + _id_sendBroadcast$1 as jni$_.JMethodIDPtr, + _$intent.pointer, _$string.pointer) - .integer; + .check(); } - static final _id_checkSelfPermission = _class.instanceMethodId( - r'checkSelfPermission', - r'(Ljava/lang/String;)I', + static final _id_sendBroadcast$2 = _class.instanceMethodId( + r'sendBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;)V', ); - static final _checkSelfPermission = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallIntMethod') + static final _sendBroadcast$2 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract int checkSelfPermission(java.lang.String string)` - int checkSelfPermission( + /// from: `public void sendBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle)` + void sendBroadcast$2( + jni$_.JObject? intent, jni$_.JString? string, + jni$_.JObject? bundle, ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - return _checkSelfPermission(reference.pointer, - _id_checkSelfPermission as jni$_.JMethodIDPtr, _$string.pointer) - .integer; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendBroadcast$2( + reference.pointer, + _id_sendBroadcast$2 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$string.pointer, + _$bundle.pointer) + .check(); } - static final _id_enforcePermission = _class.instanceMethodId( - r'enforcePermission', - r'(Ljava/lang/String;IILjava/lang/String;)V', + static final _id_sendBroadcastAsUser = _class.instanceMethodId( + r'sendBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', ); - static final _enforcePermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -47107,8 +47273,6 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< @@ -47116,41 +47280,36 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - int, - int, jni$_.Pointer)>(); - /// from: `public abstract void enforcePermission(java.lang.String string, int i, int i1, java.lang.String string1)` - void enforcePermission( - jni$_.JString? string, - int i, - int i1, - jni$_.JString? string1, + /// from: `public abstract void sendBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` + void sendBroadcastAsUser( + jni$_.JObject? intent, + jni$_.JObject? userHandle, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - _enforcePermission( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + _sendBroadcastAsUser( reference.pointer, - _id_enforcePermission as jni$_.JMethodIDPtr, - _$string.pointer, - i, - i1, - _$string1.pointer) + _id_sendBroadcastAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer) .check(); } - static final _id_enforceCallingPermission = _class.instanceMethodId( - r'enforceCallingPermission', - r'(Ljava/lang/String;Ljava/lang/String;)V', + static final _id_sendBroadcastAsUser$1 = _class.instanceMethodId( + r'sendBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;)V', ); - static final _enforceCallingPermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendBroadcastAsUser$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, jni$_.Pointer, jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') @@ -47159,29 +47318,34 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract void enforceCallingPermission(java.lang.String string, java.lang.String string1)` - void enforceCallingPermission( + /// from: `public abstract void sendBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, java.lang.String string)` + void sendBroadcastAsUser$1( + jni$_.JObject? intent, + jni$_.JObject? userHandle, jni$_.JString? string, - jni$_.JString? string1, ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - _enforceCallingPermission( + _sendBroadcastAsUser$1( reference.pointer, - _id_enforceCallingPermission as jni$_.JMethodIDPtr, - _$string.pointer, - _$string1.pointer) + _id_sendBroadcastAsUser$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer, + _$string.pointer) .check(); } - static final _id_enforceCallingOrSelfPermission = _class.instanceMethodId( - r'enforceCallingOrSelfPermission', - r'(Ljava/lang/String;Ljava/lang/String;)V', + static final _id_sendBroadcastWithMultiplePermissions = + _class.instanceMethodId( + r'sendBroadcastWithMultiplePermissions', + r'(Landroid/content/Intent;[Ljava/lang/String;)V', ); - static final _enforceCallingOrSelfPermission = + static final _sendBroadcastWithMultiplePermissions = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( @@ -47199,27 +47363,27 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract void enforceCallingOrSelfPermission(java.lang.String string, java.lang.String string1)` - void enforceCallingOrSelfPermission( - jni$_.JString? string, - jni$_.JString? string1, + /// from: `public void sendBroadcastWithMultiplePermissions(android.content.Intent intent, java.lang.String[] strings)` + void sendBroadcastWithMultiplePermissions( + jni$_.JObject? intent, + jni$_.JArray? strings, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - _enforceCallingOrSelfPermission( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$strings = strings?.reference ?? jni$_.jNullReference; + _sendBroadcastWithMultiplePermissions( reference.pointer, - _id_enforceCallingOrSelfPermission as jni$_.JMethodIDPtr, - _$string.pointer, - _$string1.pointer) + _id_sendBroadcastWithMultiplePermissions as jni$_.JMethodIDPtr, + _$intent.pointer, + _$strings.pointer) .check(); } - static final _id_grantUriPermission = _class.instanceMethodId( - r'grantUriPermission', - r'(Ljava/lang/String;Landroid/net/Uri;I)V', + static final _id_sendOrderedBroadcast = _class.instanceMethodId( + r'sendOrderedBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;)V', ); - static final _grantUriPermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendOrderedBroadcast = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -47227,68 +47391,36 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32 + jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, - int)>(); + jni$_.Pointer)>(); - /// from: `public abstract void grantUriPermission(java.lang.String string, android.net.Uri uri, int i)` - void grantUriPermission( + /// from: `public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string)` + void sendOrderedBroadcast( + jni$_.JObject? intent, jni$_.JString? string, - jni$_.JObject? uri, - int i, ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - final _$uri = uri?.reference ?? jni$_.jNullReference; - _grantUriPermission( + _sendOrderedBroadcast( reference.pointer, - _id_grantUriPermission as jni$_.JMethodIDPtr, - _$string.pointer, - _$uri.pointer, - i) - .check(); - } - - static final _id_revokeUriPermission = _class.instanceMethodId( - r'revokeUriPermission', - r'(Landroid/net/Uri;I)V', - ); - - static final _revokeUriPermission = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallVoidMethod') - .asFunction< - jni$_.JThrowablePtr Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - - /// from: `public abstract void revokeUriPermission(android.net.Uri uri, int i)` - void revokeUriPermission( - jni$_.JObject? uri, - int i, - ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - _revokeUriPermission(reference.pointer, - _id_revokeUriPermission as jni$_.JMethodIDPtr, _$uri.pointer, i) + _id_sendOrderedBroadcast as jni$_.JMethodIDPtr, + _$intent.pointer, + _$string.pointer) .check(); } - static final _id_revokeUriPermission$1 = _class.instanceMethodId( - r'revokeUriPermission', - r'(Ljava/lang/String;Landroid/net/Uri;I)V', + static final _id_sendOrderedBroadcast$1 = _class.instanceMethodId( + r'sendOrderedBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _revokeUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< + static final _sendOrderedBroadcast$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -47297,7 +47429,11 @@ class Context extends jni$_.JObject { ( jni$_.Pointer, jni$_.Pointer, - jni$_.Int32 + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< jni$_.JThrowablePtr Function( @@ -47305,344 +47441,355 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.Pointer, jni$_.Pointer, - int)>(); + jni$_.Pointer, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract void revokeUriPermission(java.lang.String string, android.net.Uri uri, int i)` - void revokeUriPermission$1( + /// from: `public abstract void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle)` + void sendOrderedBroadcast$1( + jni$_.JObject? intent, jni$_.JString? string, - jni$_.JObject? uri, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, + jni$_.JString? string1, + jni$_.JObject? bundle, ) { + final _$intent = intent?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - final _$uri = uri?.reference ?? jni$_.jNullReference; - _revokeUriPermission$1( + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendOrderedBroadcast$1( reference.pointer, - _id_revokeUriPermission$1 as jni$_.JMethodIDPtr, + _id_sendOrderedBroadcast$1 as jni$_.JMethodIDPtr, + _$intent.pointer, _$string.pointer, - _$uri.pointer, - i) + _$broadcastReceiver.pointer, + _$handler.pointer, + i, + _$string1.pointer, + _$bundle.pointer) .check(); } - static final _id_checkUriPermission = _class.instanceMethodId( - r'checkUriPermission', - r'(Landroid/net/Uri;III)I', + static final _id_sendOrderedBroadcast$2 = _class.instanceMethodId( + r'sendOrderedBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;)V', ); - static final _checkUriPermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendOrderedBroadcast$2 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallIntMethod') + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract int checkUriPermission(android.net.Uri uri, int i, int i1, int i2)` - int checkUriPermission( - jni$_.JObject? uri, - int i, - int i1, - int i2, + /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle)` + void sendOrderedBroadcast$2( + jni$_.JObject? intent, + jni$_.JString? string, + jni$_.JObject? bundle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - return _checkUriPermission( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendOrderedBroadcast$2( reference.pointer, - _id_checkUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, - i, - i1, - i2) - .integer; + _id_sendOrderedBroadcast$2 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$string.pointer, + _$bundle.pointer) + .check(); } - static final _id_checkContentUriPermissionFull = _class.instanceMethodId( - r'checkContentUriPermissionFull', - r'(Landroid/net/Uri;III)I', + static final _id_sendOrderedBroadcast$3 = _class.instanceMethodId( + r'sendOrderedBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _checkContentUriPermissionFull = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function( + static final _sendOrderedBroadcast$3 = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.Pointer, - int, - int, - int)>(); + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public int checkContentUriPermissionFull(android.net.Uri uri, int i, int i1, int i2)` - int checkContentUriPermissionFull( - jni$_.JObject? uri, + /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, android.os.Bundle bundle, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle1)` + void sendOrderedBroadcast$3( + jni$_.JObject? intent, + jni$_.JString? string, + jni$_.JObject? bundle, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, - int i1, - int i2, + jni$_.JString? string1, + jni$_.JObject? bundle1, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - return _checkContentUriPermissionFull( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + final _$bundle1 = bundle1?.reference ?? jni$_.jNullReference; + _sendOrderedBroadcast$3( reference.pointer, - _id_checkContentUriPermissionFull as jni$_.JMethodIDPtr, - _$uri.pointer, + _id_sendOrderedBroadcast$3 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$string.pointer, + _$bundle.pointer, + _$broadcastReceiver.pointer, + _$handler.pointer, i, - i1, - i2) - .integer; + _$string1.pointer, + _$bundle1.pointer) + .check(); } - static final _id_checkUriPermissions = _class.instanceMethodId( - r'checkUriPermissions', - r'(Ljava/util/List;III)[I', + static final _id_sendOrderedBroadcast$4 = _class.instanceMethodId( + r'sendOrderedBroadcast', + r'(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _checkUriPermissions = jni$_.ProtectedJniExtensions.lookup< + static final _sendOrderedBroadcast$4 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, jni$_.Pointer, jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallObjectMethod') + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int, int, int)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public int[] checkUriPermissions(java.util.List list, int i, int i1, int i2)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JIntArray? checkUriPermissions( - jni$_.JList? list, + /// from: `public void sendOrderedBroadcast(android.content.Intent intent, java.lang.String string, java.lang.String string1, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string2, android.os.Bundle bundle)` + void sendOrderedBroadcast$4( + jni$_.JObject? intent, + jni$_.JString? string, + jni$_.JString? string1, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, - int i1, - int i2, + jni$_.JString? string2, + jni$_.JObject? bundle, ) { - final _$list = list?.reference ?? jni$_.jNullReference; - return _checkUriPermissions( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + final _$string2 = string2?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendOrderedBroadcast$4( reference.pointer, - _id_checkUriPermissions as jni$_.JMethodIDPtr, - _$list.pointer, + _id_sendOrderedBroadcast$4 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$string.pointer, + _$string1.pointer, + _$broadcastReceiver.pointer, + _$handler.pointer, i, - i1, - i2) - .object(const jni$_.JIntArrayNullableType()); - } - - static final _id_checkCallingUriPermission = _class.instanceMethodId( - r'checkCallingUriPermission', - r'(Landroid/net/Uri;I)I', - ); - - static final _checkCallingUriPermission = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallIntMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - - /// from: `public abstract int checkCallingUriPermission(android.net.Uri uri, int i)` - int checkCallingUriPermission( - jni$_.JObject? uri, - int i, - ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - return _checkCallingUriPermission( - reference.pointer, - _id_checkCallingUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, - i) - .integer; + _$string2.pointer, + _$bundle.pointer) + .check(); } - static final _id_checkCallingUriPermissions = _class.instanceMethodId( - r'checkCallingUriPermissions', - r'(Ljava/util/List;I)[I', + static final _id_sendOrderedBroadcastAsUser = _class.instanceMethodId( + r'sendOrderedBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _checkCallingUriPermissions = + static final _sendOrderedBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32 - )>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); - - /// from: `public int[] checkCallingUriPermissions(java.util.List list, int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JIntArray? checkCallingUriPermissions( - jni$_.JList? list, - int i, - ) { - final _$list = list?.reference ?? jni$_.jNullReference; - return _checkCallingUriPermissions( - reference.pointer, - _id_checkCallingUriPermissions as jni$_.JMethodIDPtr, - _$list.pointer, - i) - .object(const jni$_.JIntArrayNullableType()); - } - - static final _id_checkCallingOrSelfUriPermission = _class.instanceMethodId( - r'checkCallingOrSelfUriPermission', - r'(Landroid/net/Uri;I)I', - ); - - static final _checkCallingOrSelfUriPermission = - jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( jni$_.Pointer, - jni$_.Int32 - )>)>>('globalEnv_CallIntMethod') + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + int, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public abstract int checkCallingOrSelfUriPermission(android.net.Uri uri, int i)` - int checkCallingOrSelfUriPermission( - jni$_.JObject? uri, + /// from: `public abstract void sendOrderedBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, java.lang.String string, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string1, android.os.Bundle bundle)` + void sendOrderedBroadcastAsUser( + jni$_.JObject? intent, + jni$_.JObject? userHandle, + jni$_.JString? string, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, + jni$_.JString? string1, + jni$_.JObject? bundle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - return _checkCallingOrSelfUriPermission( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; + final _$string1 = string1?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendOrderedBroadcastAsUser( reference.pointer, - _id_checkCallingOrSelfUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, - i) - .integer; + _id_sendOrderedBroadcastAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer, + _$string.pointer, + _$broadcastReceiver.pointer, + _$handler.pointer, + i, + _$string1.pointer, + _$bundle.pointer) + .check(); } - static final _id_checkCallingOrSelfUriPermissions = _class.instanceMethodId( - r'checkCallingOrSelfUriPermissions', - r'(Ljava/util/List;I)[I', + static final _id_sendStickyBroadcast = _class.instanceMethodId( + r'sendStickyBroadcast', + r'(Landroid/content/Intent;)V', ); - static final _checkCallingOrSelfUriPermissions = - jni$_.ProtectedJniExtensions.lookup< + static final _sendStickyBroadcast = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Int32 - )>)>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') + .asFunction< + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public int[] checkCallingOrSelfUriPermissions(java.util.List list, int i)` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JIntArray? checkCallingOrSelfUriPermissions( - jni$_.JList? list, - int i, + /// from: `public abstract void sendStickyBroadcast(android.content.Intent intent)` + void sendStickyBroadcast( + jni$_.JObject? intent, ) { - final _$list = list?.reference ?? jni$_.jNullReference; - return _checkCallingOrSelfUriPermissions( - reference.pointer, - _id_checkCallingOrSelfUriPermissions as jni$_.JMethodIDPtr, - _$list.pointer, - i) - .object(const jni$_.JIntArrayNullableType()); + final _$intent = intent?.reference ?? jni$_.jNullReference; + _sendStickyBroadcast(reference.pointer, + _id_sendStickyBroadcast as jni$_.JMethodIDPtr, _$intent.pointer) + .check(); } - static final _id_checkUriPermission$1 = _class.instanceMethodId( - r'checkUriPermission', - r'(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;III)I', + static final _id_sendStickyBroadcast$1 = _class.instanceMethodId( + r'sendStickyBroadcast', + r'(Landroid/content/Intent;Landroid/os/Bundle;)V', ); - static final _checkUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< + static final _sendStickyBroadcast$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32 - )>)>>('globalEnv_CallIntMethod') + jni$_.Pointer + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - int, - int)>(); + jni$_.Pointer)>(); - /// from: `public abstract int checkUriPermission(android.net.Uri uri, java.lang.String string, java.lang.String string1, int i, int i1, int i2)` - int checkUriPermission$1( - jni$_.JObject? uri, - jni$_.JString? string, - jni$_.JString? string1, - int i, - int i1, - int i2, + /// from: `public void sendStickyBroadcast(android.content.Intent intent, android.os.Bundle bundle)` + void sendStickyBroadcast$1( + jni$_.JObject? intent, + jni$_.JObject? bundle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - return _checkUriPermission$1( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendStickyBroadcast$1( reference.pointer, - _id_checkUriPermission$1 as jni$_.JMethodIDPtr, - _$uri.pointer, - _$string.pointer, - _$string1.pointer, - i, - i1, - i2) - .integer; + _id_sendStickyBroadcast$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$bundle.pointer) + .check(); } - static final _id_enforceUriPermission = _class.instanceMethodId( - r'enforceUriPermission', - r'(Landroid/net/Uri;IIILjava/lang/String;)V', + static final _id_sendStickyBroadcastAsUser = _class.instanceMethodId( + r'sendStickyBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;)V', ); - static final _enforceUriPermission = jni$_.ProtectedJniExtensions.lookup< + static final _sendStickyBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, @@ -47650,9 +47797,6 @@ class Context extends jni$_.JObject { jni$_.VarArgs< ( jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< @@ -47660,38 +47804,29 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, - int, - int, - int, jni$_.Pointer)>(); - /// from: `public abstract void enforceUriPermission(android.net.Uri uri, int i, int i1, int i2, java.lang.String string)` - void enforceUriPermission( - jni$_.JObject? uri, - int i, - int i1, - int i2, - jni$_.JString? string, + /// from: `public abstract void sendStickyBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle)` + void sendStickyBroadcastAsUser( + jni$_.JObject? intent, + jni$_.JObject? userHandle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - _enforceUriPermission( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + _sendStickyBroadcastAsUser( reference.pointer, - _id_enforceUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, - i, - i1, - i2, - _$string.pointer) + _id_sendStickyBroadcastAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer) .check(); } - static final _id_enforceCallingUriPermission = _class.instanceMethodId( - r'enforceCallingUriPermission', - r'(Landroid/net/Uri;ILjava/lang/String;)V', + static final _id_sendStickyOrderedBroadcast = _class.instanceMethodId( + r'sendStickyOrderedBroadcast', + r'(Landroid/content/Intent;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _enforceCallingUriPermission = + static final _sendStickyOrderedBroadcast = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( @@ -47699,8 +47834,11 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, + jni$_.Pointer, jni$_.Pointer, jni$_.Int32, + jni$_.Pointer, jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< @@ -47708,32 +47846,45 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, int, + jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract void enforceCallingUriPermission(android.net.Uri uri, int i, java.lang.String string)` - void enforceCallingUriPermission( - jni$_.JObject? uri, + /// from: `public abstract void sendStickyOrderedBroadcast(android.content.Intent intent, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string, android.os.Bundle bundle)` + void sendStickyOrderedBroadcast( + jni$_.JObject? intent, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, jni$_.JString? string, + jni$_.JObject? bundle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - _enforceCallingUriPermission( + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendStickyOrderedBroadcast( reference.pointer, - _id_enforceCallingUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, + _id_sendStickyOrderedBroadcast as jni$_.JMethodIDPtr, + _$intent.pointer, + _$broadcastReceiver.pointer, + _$handler.pointer, i, - _$string.pointer) + _$string.pointer, + _$bundle.pointer) .check(); } - static final _id_enforceCallingOrSelfUriPermission = _class.instanceMethodId( - r'enforceCallingOrSelfUriPermission', - r'(Landroid/net/Uri;ILjava/lang/String;)V', + static final _id_sendStickyOrderedBroadcastAsUser = _class.instanceMethodId( + r'sendStickyOrderedBroadcastAsUser', + r'(Landroid/content/Intent;Landroid/os/UserHandle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V', ); - static final _enforceCallingOrSelfUriPermission = + static final _sendStickyOrderedBroadcastAsUser = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( @@ -47741,8 +47892,12 @@ class Context extends jni$_.JObject { jni$_.JMethodIDPtr, jni$_.VarArgs< ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, jni$_.Pointer, jni$_.Int32, + jni$_.Pointer, jni$_.Pointer )>)>>('globalEnv_CallVoidMethod') .asFunction< @@ -47750,235 +47905,249 @@ class Context extends jni$_.JObject { jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer, int, + jni$_.Pointer, jni$_.Pointer)>(); - /// from: `public abstract void enforceCallingOrSelfUriPermission(android.net.Uri uri, int i, java.lang.String string)` - void enforceCallingOrSelfUriPermission( - jni$_.JObject? uri, + /// from: `public abstract void sendStickyOrderedBroadcastAsUser(android.content.Intent intent, android.os.UserHandle userHandle, android.content.BroadcastReceiver broadcastReceiver, android.os.Handler handler, int i, java.lang.String string, android.os.Bundle bundle)` + void sendStickyOrderedBroadcastAsUser( + jni$_.JObject? intent, + jni$_.JObject? userHandle, + jni$_.JObject? broadcastReceiver, + jni$_.JObject? handler, int i, jni$_.JString? string, + jni$_.JObject? bundle, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$userHandle = userHandle?.reference ?? jni$_.jNullReference; + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + final _$handler = handler?.reference ?? jni$_.jNullReference; final _$string = string?.reference ?? jni$_.jNullReference; - _enforceCallingOrSelfUriPermission( + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _sendStickyOrderedBroadcastAsUser( reference.pointer, - _id_enforceCallingOrSelfUriPermission as jni$_.JMethodIDPtr, - _$uri.pointer, + _id_sendStickyOrderedBroadcastAsUser as jni$_.JMethodIDPtr, + _$intent.pointer, + _$userHandle.pointer, + _$broadcastReceiver.pointer, + _$handler.pointer, i, - _$string.pointer) + _$string.pointer, + _$bundle.pointer) .check(); } - static final _id_enforceUriPermission$1 = _class.instanceMethodId( - r'enforceUriPermission', - r'(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;)V', + static final _id_setTheme = _class.instanceMethodId( + r'setTheme', + r'(I)V', ); - static final _enforceUriPermission$1 = jni$_.ProtectedJniExtensions.lookup< + static final _setTheme = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Int32, - jni$_.Int32, - jni$_.Int32, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod') .asFunction< jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.Pointer, - jni$_.Pointer, - jni$_.Pointer, - int, - int, - int, - jni$_.Pointer)>(); + jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); - /// from: `public abstract void enforceUriPermission(android.net.Uri uri, java.lang.String string, java.lang.String string1, int i, int i1, int i2, java.lang.String string2)` - void enforceUriPermission$1( - jni$_.JObject? uri, - jni$_.JString? string, - jni$_.JString? string1, + /// from: `public abstract void setTheme(int i)` + void setTheme( int i, - int i1, - int i2, - jni$_.JString? string2, ) { - final _$uri = uri?.reference ?? jni$_.jNullReference; - final _$string = string?.reference ?? jni$_.jNullReference; - final _$string1 = string1?.reference ?? jni$_.jNullReference; - final _$string2 = string2?.reference ?? jni$_.jNullReference; - _enforceUriPermission$1( - reference.pointer, - _id_enforceUriPermission$1 as jni$_.JMethodIDPtr, - _$uri.pointer, - _$string.pointer, - _$string1.pointer, - i, - i1, - i2, - _$string2.pointer) - .check(); + _setTheme(reference.pointer, _id_setTheme as jni$_.JMethodIDPtr, i).check(); } - static final _id_revokeSelfPermissionOnKill = _class.instanceMethodId( - r'revokeSelfPermissionOnKill', - r'(Ljava/lang/String;)V', + static final _id_setWallpaper = _class.instanceMethodId( + r'setWallpaper', + r'(Landroid/graphics/Bitmap;)V', ); - static final _revokeSelfPermissionOnKill = - 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)>(); + static final _setWallpaper = 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 revokeSelfPermissionOnKill(java.lang.String string)` - void revokeSelfPermissionOnKill( - jni$_.JString? string, + /// from: `public abstract void setWallpaper(android.graphics.Bitmap bitmap)` + void setWallpaper( + Bitmap? bitmap, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - _revokeSelfPermissionOnKill( - reference.pointer, - _id_revokeSelfPermissionOnKill as jni$_.JMethodIDPtr, - _$string.pointer) + final _$bitmap = bitmap?.reference ?? jni$_.jNullReference; + _setWallpaper(reference.pointer, _id_setWallpaper as jni$_.JMethodIDPtr, + _$bitmap.pointer) .check(); } - static final _id_revokeSelfPermissionsOnKill = _class.instanceMethodId( - r'revokeSelfPermissionsOnKill', - r'(Ljava/util/Collection;)V', + static final _id_setWallpaper$1 = _class.instanceMethodId( + r'setWallpaper', + r'(Ljava/io/InputStream;)V', ); - static final _revokeSelfPermissionsOnKill = - 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)>(); + static final _setWallpaper$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 revokeSelfPermissionsOnKill(java.util.Collection collection)` - void revokeSelfPermissionsOnKill( - jni$_.JObject? collection, + /// from: `public abstract void setWallpaper(java.io.InputStream inputStream)` + void setWallpaper$1( + jni$_.JObject? inputStream, ) { - final _$collection = collection?.reference ?? jni$_.jNullReference; - _revokeSelfPermissionsOnKill( - reference.pointer, - _id_revokeSelfPermissionsOnKill as jni$_.JMethodIDPtr, - _$collection.pointer) + final _$inputStream = inputStream?.reference ?? jni$_.jNullReference; + _setWallpaper$1(reference.pointer, _id_setWallpaper$1 as jni$_.JMethodIDPtr, + _$inputStream.pointer) .check(); } - static final _id_createPackageContext = _class.instanceMethodId( - r'createPackageContext', - r'(Ljava/lang/String;I)Landroid/content/Context;', + static final _id_startActivities = _class.instanceMethodId( + r'startActivities', + r'([Landroid/content/Intent;)V', ); - static final _createPackageContext = jni$_.ProtectedJniExtensions.lookup< + static final _startActivities = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Pointer, jni$_.Int32)>)>>( - 'globalEnv_CallObjectMethod') + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, jni$_.Pointer, int)>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract android.content.Context createPackageContext(java.lang.String string, int i)` - /// The returned object must be released after use, by calling the [release] method. - Context? createPackageContext( - jni$_.JString? string, - int i, + /// from: `public abstract void startActivities(android.content.Intent[] intents)` + void startActivities( + jni$_.JArray? intents, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _createPackageContext(reference.pointer, - _id_createPackageContext as jni$_.JMethodIDPtr, _$string.pointer, i) - .object(const $Context$NullableType()); + final _$intents = intents?.reference ?? jni$_.jNullReference; + _startActivities(reference.pointer, + _id_startActivities as jni$_.JMethodIDPtr, _$intents.pointer) + .check(); } - static final _id_createContextForSplit = _class.instanceMethodId( - r'createContextForSplit', - r'(Ljava/lang/String;)Landroid/content/Context;', + static final _id_startActivities$1 = _class.instanceMethodId( + r'startActivities', + r'([Landroid/content/Intent;Landroid/os/Bundle;)V', ); - static final _createContextForSplit = jni$_.ProtectedJniExtensions.lookup< + static final _startActivities$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 abstract void startActivities(android.content.Intent[] intents, android.os.Bundle bundle)` + void startActivities$1( + jni$_.JArray? intents, + jni$_.JObject? bundle, + ) { + final _$intents = intents?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _startActivities$1( + reference.pointer, + _id_startActivities$1 as jni$_.JMethodIDPtr, + _$intents.pointer, + _$bundle.pointer) + .check(); + } + + static final _id_startActivity = _class.instanceMethodId( + r'startActivity', + r'(Landroid/content/Intent;)V', + ); + + static final _startActivity = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, + jni$_.JThrowablePtr Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract android.content.Context createContextForSplit(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - Context? createContextForSplit( - jni$_.JString? string, + /// from: `public abstract void startActivity(android.content.Intent intent)` + void startActivity( + jni$_.JObject? intent, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _createContextForSplit(reference.pointer, - _id_createContextForSplit as jni$_.JMethodIDPtr, _$string.pointer) - .object(const $Context$NullableType()); - } - - static final _id_createConfigurationContext = _class.instanceMethodId( - r'createConfigurationContext', - r'(Landroid/content/res/Configuration;)Landroid/content/Context;', - ); - - static final _createConfigurationContext = - 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)>(); + final _$intent = intent?.reference ?? jni$_.jNullReference; + _startActivity(reference.pointer, _id_startActivity as jni$_.JMethodIDPtr, + _$intent.pointer) + .check(); + } - /// from: `public abstract android.content.Context createConfigurationContext(android.content.res.Configuration configuration)` - /// The returned object must be released after use, by calling the [release] method. - Context? createConfigurationContext( - jni$_.JObject? configuration, + static final _id_startActivity$1 = _class.instanceMethodId( + r'startActivity', + r'(Landroid/content/Intent;Landroid/os/Bundle;)V', + ); + + static final _startActivity$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 abstract void startActivity(android.content.Intent intent, android.os.Bundle bundle)` + void startActivity$1( + jni$_.JObject? intent, + jni$_.JObject? bundle, ) { - final _$configuration = configuration?.reference ?? jni$_.jNullReference; - return _createConfigurationContext( + final _$intent = intent?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + _startActivity$1( reference.pointer, - _id_createConfigurationContext as jni$_.JMethodIDPtr, - _$configuration.pointer) - .object(const $Context$NullableType()); + _id_startActivity$1 as jni$_.JMethodIDPtr, + _$intent.pointer, + _$bundle.pointer) + .check(); } - static final _id_createDisplayContext = _class.instanceMethodId( - r'createDisplayContext', - r'(Landroid/view/Display;)Landroid/content/Context;', + static final _id_startForegroundService = _class.instanceMethodId( + r'startForegroundService', + r'(Landroid/content/Intent;)Landroid/content/ComponentName;', ); - static final _createDisplayContext = jni$_.ProtectedJniExtensions.lookup< + static final _startForegroundService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -47989,119 +48158,168 @@ class Context extends jni$_.JObject { jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract android.content.Context createDisplayContext(android.view.Display display)` + /// from: `public abstract android.content.ComponentName startForegroundService(android.content.Intent intent)` /// The returned object must be released after use, by calling the [release] method. - Context? createDisplayContext( - jni$_.JObject? display, + jni$_.JObject? startForegroundService( + jni$_.JObject? intent, ) { - final _$display = display?.reference ?? jni$_.jNullReference; - return _createDisplayContext(reference.pointer, - _id_createDisplayContext as jni$_.JMethodIDPtr, _$display.pointer) - .object(const $Context$NullableType()); + final _$intent = intent?.reference ?? jni$_.jNullReference; + return _startForegroundService(reference.pointer, + _id_startForegroundService as jni$_.JMethodIDPtr, _$intent.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_createDeviceContext = _class.instanceMethodId( - r'createDeviceContext', - r'(I)Landroid/content/Context;', + static final _id_startInstrumentation = _class.instanceMethodId( + r'startInstrumentation', + r'(Landroid/content/ComponentName;Ljava/lang/String;Landroid/os/Bundle;)Z', ); - static final _createDeviceContext = jni$_.ProtectedJniExtensions.lookup< + static final _startInstrumentation = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, - jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod') + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer + )>)>>('globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function( - jni$_.Pointer, jni$_.JMethodIDPtr, int)>(); + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + jni$_.Pointer)>(); - /// from: `public android.content.Context createDeviceContext(int i)` - /// The returned object must be released after use, by calling the [release] method. - Context? createDeviceContext( - int i, + /// from: `public abstract boolean startInstrumentation(android.content.ComponentName componentName, java.lang.String string, android.os.Bundle bundle)` + bool startInstrumentation( + jni$_.JObject? componentName, + jni$_.JString? string, + jni$_.JObject? bundle, ) { - return _createDeviceContext( - reference.pointer, _id_createDeviceContext as jni$_.JMethodIDPtr, i) - .object(const $Context$NullableType()); + final _$componentName = componentName?.reference ?? jni$_.jNullReference; + final _$string = string?.reference ?? jni$_.jNullReference; + final _$bundle = bundle?.reference ?? jni$_.jNullReference; + return _startInstrumentation( + reference.pointer, + _id_startInstrumentation as jni$_.JMethodIDPtr, + _$componentName.pointer, + _$string.pointer, + _$bundle.pointer) + .boolean; } - static final _id_createWindowContext = _class.instanceMethodId( - r'createWindowContext', - r'(ILandroid/os/Bundle;)Landroid/content/Context;', + static final _id_startIntentSender = _class.instanceMethodId( + r'startIntentSender', + r'(Landroid/content/IntentSender;Landroid/content/Intent;III)V', ); - static final _createWindowContext = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_ - .VarArgs<(jni$_.Int32, jni$_.Pointer)>)>>( - 'globalEnv_CallObjectMethod') + static final _startIntentSender = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function(jni$_.Pointer, - jni$_.JMethodIDPtr, int, jni$_.Pointer)>(); + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.Pointer, + jni$_.Pointer, + int, + int, + int)>(); - /// from: `public android.content.Context createWindowContext(int i, android.os.Bundle bundle)` - /// The returned object must be released after use, by calling the [release] method. - Context? createWindowContext( + /// from: `public abstract void startIntentSender(android.content.IntentSender intentSender, android.content.Intent intent, int i, int i1, int i2)` + void startIntentSender( + jni$_.JObject? intentSender, + jni$_.JObject? intent, int i, - jni$_.JObject? bundle, + int i1, + int i2, ) { - final _$bundle = bundle?.reference ?? jni$_.jNullReference; - return _createWindowContext(reference.pointer, - _id_createWindowContext as jni$_.JMethodIDPtr, i, _$bundle.pointer) - .object(const $Context$NullableType()); + final _$intentSender = intentSender?.reference ?? jni$_.jNullReference; + final _$intent = intent?.reference ?? jni$_.jNullReference; + _startIntentSender( + reference.pointer, + _id_startIntentSender as jni$_.JMethodIDPtr, + _$intentSender.pointer, + _$intent.pointer, + i, + i1, + i2) + .check(); } - static final _id_createWindowContext$1 = _class.instanceMethodId( - r'createWindowContext', - r'(Landroid/view/Display;ILandroid/os/Bundle;)Landroid/content/Context;', + static final _id_startIntentSender$1 = _class.instanceMethodId( + r'startIntentSender', + r'(Landroid/content/IntentSender;Landroid/content/Intent;IIILandroid/os/Bundle;)V', ); - static final _createWindowContext$1 = jni$_.ProtectedJniExtensions.lookup< + static final _startIntentSender$1 = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs< ( jni$_.Pointer, + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32, jni$_.Int32, jni$_.Pointer - )>)>>('globalEnv_CallObjectMethod') + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( + jni$_.JThrowablePtr Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer, + jni$_.Pointer, + int, + int, int, jni$_.Pointer)>(); - /// from: `public android.content.Context createWindowContext(android.view.Display display, int i, android.os.Bundle bundle)` - /// The returned object must be released after use, by calling the [release] method. - Context? createWindowContext$1( - jni$_.JObject? display, + /// from: `public abstract void startIntentSender(android.content.IntentSender intentSender, android.content.Intent intent, int i, int i1, int i2, android.os.Bundle bundle)` + void startIntentSender$1( + jni$_.JObject? intentSender, + jni$_.JObject? intent, int i, + int i1, + int i2, jni$_.JObject? bundle, ) { - final _$display = display?.reference ?? jni$_.jNullReference; + final _$intentSender = intentSender?.reference ?? jni$_.jNullReference; + final _$intent = intent?.reference ?? jni$_.jNullReference; final _$bundle = bundle?.reference ?? jni$_.jNullReference; - return _createWindowContext$1( + _startIntentSender$1( reference.pointer, - _id_createWindowContext$1 as jni$_.JMethodIDPtr, - _$display.pointer, + _id_startIntentSender$1 as jni$_.JMethodIDPtr, + _$intentSender.pointer, + _$intent.pointer, i, + i1, + i2, _$bundle.pointer) - .object(const $Context$NullableType()); + .check(); } - static final _id_createContext = _class.instanceMethodId( - r'createContext', - r'(Landroid/content/ContextParams;)Landroid/content/Context;', + static final _id_startService = _class.instanceMethodId( + r'startService', + r'(Landroid/content/Intent;)Landroid/content/ComponentName;', ); - static final _createContext = jni$_.ProtectedJniExtensions.lookup< + static final _startService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, @@ -48112,156 +48330,97 @@ class Context extends jni$_.JObject { jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public android.content.Context createContext(android.content.ContextParams contextParams)` + /// from: `public abstract android.content.ComponentName startService(android.content.Intent intent)` /// The returned object must be released after use, by calling the [release] method. - Context? createContext( - jni$_.JObject? contextParams, + jni$_.JObject? startService( + jni$_.JObject? intent, ) { - final _$contextParams = contextParams?.reference ?? jni$_.jNullReference; - return _createContext(reference.pointer, - _id_createContext as jni$_.JMethodIDPtr, _$contextParams.pointer) - .object(const $Context$NullableType()); + final _$intent = intent?.reference ?? jni$_.jNullReference; + return _startService(reference.pointer, + _id_startService as jni$_.JMethodIDPtr, _$intent.pointer) + .object(const jni$_.JObjectNullableType()); } - static final _id_createAttributionContext = _class.instanceMethodId( - r'createAttributionContext', - r'(Ljava/lang/String;)Landroid/content/Context;', + static final _id_stopService = _class.instanceMethodId( + r'stopService', + r'(Landroid/content/Intent;)Z', ); - static final _createAttributionContext = jni$_.ProtectedJniExtensions.lookup< + static final _stopService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< jni$_.JniResult Function( jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Pointer,)>)>>( - 'globalEnv_CallObjectMethod') + 'globalEnv_CallBooleanMethod') .asFunction< jni$_.JniResult Function(jni$_.Pointer, jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public android.content.Context createAttributionContext(java.lang.String string)` - /// The returned object must be released after use, by calling the [release] method. - Context? createAttributionContext( - jni$_.JString? string, + /// from: `public abstract boolean stopService(android.content.Intent intent)` + bool stopService( + jni$_.JObject? intent, ) { - final _$string = string?.reference ?? jni$_.jNullReference; - return _createAttributionContext( - reference.pointer, - _id_createAttributionContext as jni$_.JMethodIDPtr, - _$string.pointer) - .object(const $Context$NullableType()); + final _$intent = intent?.reference ?? jni$_.jNullReference; + return _stopService(reference.pointer, + _id_stopService as jni$_.JMethodIDPtr, _$intent.pointer) + .boolean; } - static final _id_createDeviceProtectedStorageContext = - _class.instanceMethodId( - r'createDeviceProtectedStorageContext', - r'()Landroid/content/Context;', + static final _id_unbindService = _class.instanceMethodId( + r'unbindService', + r'(Landroid/content/ServiceConnection;)V', ); - static final _createDeviceProtectedStorageContext = - jni$_.ProtectedJniExtensions.lookup< + static final _unbindService = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public abstract android.content.Context createDeviceProtectedStorageContext()` - /// The returned object must be released after use, by calling the [release] method. - Context? createDeviceProtectedStorageContext() { - return _createDeviceProtectedStorageContext(reference.pointer, - _id_createDeviceProtectedStorageContext as jni$_.JMethodIDPtr) - .object(const $Context$NullableType()); - } - - static final _id_getDisplay = _class.instanceMethodId( - r'getDisplay', - r'()Landroid/view/Display;', - ); - - static final _getDisplay = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallObjectMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public android.view.Display getDisplay()` - /// The returned object must be released after use, by calling the [release] method. - jni$_.JObject? getDisplay() { - return _getDisplay(reference.pointer, _id_getDisplay as jni$_.JMethodIDPtr) - .object(const jni$_.JObjectNullableType()); - } - - static final _id_getDeviceId = _class.instanceMethodId( - r'getDeviceId', - r'()I', - ); - - static final _getDeviceId = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallIntMethod') + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public int getDeviceId()` - int getDeviceId() { - return _getDeviceId( - reference.pointer, _id_getDeviceId as jni$_.JMethodIDPtr) - .integer; + /// from: `public abstract void unbindService(android.content.ServiceConnection serviceConnection)` + void unbindService( + jni$_.JObject? serviceConnection, + ) { + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + _unbindService(reference.pointer, _id_unbindService as jni$_.JMethodIDPtr, + _$serviceConnection.pointer) + .check(); } - static final _id_registerDeviceIdChangeListener = _class.instanceMethodId( - r'registerDeviceIdChangeListener', - r'(Ljava/util/concurrent/Executor;Ljava/util/function/IntConsumer;)V', + static final _id_unregisterComponentCallbacks = _class.instanceMethodId( + r'unregisterComponentCallbacks', + r'(Landroid/content/ComponentCallbacks;)V', ); - static final _registerDeviceIdChangeListener = + static final _unregisterComponentCallbacks = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JThrowablePtr Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - jni$_.VarArgs< - ( - jni$_.Pointer, - jni$_.Pointer - )>)>>('globalEnv_CallVoidMethod') + 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, - jni$_.Pointer)>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public void registerDeviceIdChangeListener(java.util.concurrent.Executor executor, java.util.function.IntConsumer intConsumer)` - void registerDeviceIdChangeListener( - jni$_.JObject? executor, - jni$_.JObject? intConsumer, + /// from: `public void unregisterComponentCallbacks(android.content.ComponentCallbacks componentCallbacks)` + void unregisterComponentCallbacks( + jni$_.JObject? componentCallbacks, ) { - final _$executor = executor?.reference ?? jni$_.jNullReference; - final _$intConsumer = intConsumer?.reference ?? jni$_.jNullReference; - _registerDeviceIdChangeListener( + final _$componentCallbacks = + componentCallbacks?.reference ?? jni$_.jNullReference; + _unregisterComponentCallbacks( reference.pointer, - _id_registerDeviceIdChangeListener as jni$_.JMethodIDPtr, - _$executor.pointer, - _$intConsumer.pointer) + _id_unregisterComponentCallbacks as jni$_.JMethodIDPtr, + _$componentCallbacks.pointer) .check(); } @@ -48294,76 +48453,70 @@ class Context extends jni$_.JObject { .check(); } - static final _id_isRestricted = _class.instanceMethodId( - r'isRestricted', - r'()Z', - ); - - static final _isRestricted = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') - .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); - - /// from: `public boolean isRestricted()` - bool isRestricted() { - return _isRestricted( - reference.pointer, _id_isRestricted as jni$_.JMethodIDPtr) - .boolean; - } - - static final _id_isDeviceProtectedStorage = _class.instanceMethodId( - r'isDeviceProtectedStorage', - r'()Z', + static final _id_unregisterReceiver = _class.instanceMethodId( + r'unregisterReceiver', + r'(Landroid/content/BroadcastReceiver;)V', ); - static final _isDeviceProtectedStorage = jni$_.ProtectedJniExtensions.lookup< - jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + static final _unregisterReceiver = jni$_.ProtectedJniExtensions.lookup< + jni$_.NativeFunction< + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs<(jni$_.Pointer,)>)>>( + 'globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer)>(); - /// from: `public abstract boolean isDeviceProtectedStorage()` - bool isDeviceProtectedStorage() { - return _isDeviceProtectedStorage(reference.pointer, - _id_isDeviceProtectedStorage as jni$_.JMethodIDPtr) - .boolean; + /// from: `public abstract void unregisterReceiver(android.content.BroadcastReceiver broadcastReceiver)` + void unregisterReceiver( + jni$_.JObject? broadcastReceiver, + ) { + final _$broadcastReceiver = + broadcastReceiver?.reference ?? jni$_.jNullReference; + _unregisterReceiver( + reference.pointer, + _id_unregisterReceiver as jni$_.JMethodIDPtr, + _$broadcastReceiver.pointer) + .check(); } - static final _id_isUiContext = _class.instanceMethodId( - r'isUiContext', - r'()Z', + static final _id_updateServiceGroup = _class.instanceMethodId( + r'updateServiceGroup', + r'(Landroid/content/ServiceConnection;II)V', ); - static final _isUiContext = jni$_.ProtectedJniExtensions.lookup< + static final _updateServiceGroup = jni$_.ProtectedJniExtensions.lookup< jni$_.NativeFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>>('globalEnv_CallBooleanMethod') + jni$_.JThrowablePtr Function( + jni$_.Pointer, + jni$_.JMethodIDPtr, + jni$_.VarArgs< + ( + jni$_.Pointer, + jni$_.Int32, + jni$_.Int32 + )>)>>('globalEnv_CallVoidMethod') .asFunction< - jni$_.JniResult Function( - jni$_.Pointer, - jni$_.JMethodIDPtr, - )>(); + jni$_.JThrowablePtr Function(jni$_.Pointer, + jni$_.JMethodIDPtr, jni$_.Pointer, int, int)>(); - /// from: `public boolean isUiContext()` - bool isUiContext() { - return _isUiContext( - reference.pointer, _id_isUiContext as jni$_.JMethodIDPtr) - .boolean; + /// from: `public void updateServiceGroup(android.content.ServiceConnection serviceConnection, int i, int i1)` + void updateServiceGroup( + jni$_.JObject? serviceConnection, + int i, + int i1, + ) { + final _$serviceConnection = + serviceConnection?.reference ?? jni$_.jNullReference; + _updateServiceGroup( + reference.pointer, + _id_updateServiceGroup as jni$_.JMethodIDPtr, + _$serviceConnection.pointer, + i, + i1) + .check(); } } From 78c3c0711f5a383e3ef947e920d641c53039709b Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Thu, 19 Feb 2026 15:02:16 +0100 Subject: [PATCH 61/62] internal(web): add sdk name for native js errors (#3525) * Add beforeSend to change sdk name in JS * Add beforeSend to js * Review * Cleanup * Update factory for creating JsSdkInfo --- CHANGELOG.md | 6 ++ .../lib/src/web/web_sentry_js_binding.dart | 25 ++++- .../test/web/web_sentry_js_binding_test.dart | 102 ++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80dbf760cb..818e456455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,12 @@ - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#8330) - [diff](https://github.com/getsentry/sentry-java/compare/8.32.0...8.33.0) +Internal Changes + +- Add `sentry.javascript.browser.flutter` sdk name for native js errors ([#3525](https://github.com/getsentry/sentry-dart/pull/3525)) + + + ## 9.13.0 ### Features diff --git a/packages/flutter/lib/src/web/web_sentry_js_binding.dart b/packages/flutter/lib/src/web/web_sentry_js_binding.dart index 0bef204fad..bdbbffdd6f 100644 --- a/packages/flutter/lib/src/web/web_sentry_js_binding.dart +++ b/packages/flutter/lib/src/web/web_sentry_js_binding.dart @@ -5,6 +5,9 @@ import 'package:meta/meta.dart'; import 'sentry_js_binding.dart'; +@visibleForTesting +const String jsSdkName = 'sentry.javascript.browser.flutter'; + SentryJsBinding createJsBinding() { return WebSentryJsBinding(); } @@ -26,11 +29,18 @@ class WebSentryJsBinding implements SentryJsBinding { options['defaultIntegrations'] = options['defaultIntegrations'] .map((String integration) => _createIntegration(integration)); } - _init(options.jsify()); + final jsOptions = options.jsify() as JSObject; + jsOptions['beforeSend'] = _beforeSend.toJS; + _init(jsOptions); _client = SentryJsClient(); _options = _client?.getOptions(); } + static _JsErrorEvent? _beforeSend(_JsErrorEvent event, JSAny? _) { + (event.sdk ??= _JsSdkInfo()).name = jsSdkName.toJS; + return event; + } + @override void updateSession({int? errors, String? status}) { final isolationScope = SentryJsIsolationScope(); @@ -215,3 +225,16 @@ external JSObject _dedupeIntegration(); @JS('globalThis') @internal external JSObject get globalThis; + +@JS() +extension type _JsErrorEvent._(JSObject _) implements JSObject { + external _JsSdkInfo? get sdk; + external set sdk(_JsSdkInfo? value); +} + +@JS() +extension type _JsSdkInfo._(JSObject _) implements JSObject { + external set name(JSString value); + + factory _JsSdkInfo() => _JsSdkInfo._(JSObject()); +} diff --git a/packages/flutter/test/web/web_sentry_js_binding_test.dart b/packages/flutter/test/web/web_sentry_js_binding_test.dart index 9da41db0e9..7599ff588e 100644 --- a/packages/flutter/test/web/web_sentry_js_binding_test.dart +++ b/packages/flutter/test/web/web_sentry_js_binding_test.dart @@ -1,6 +1,7 @@ @TestOn('browser') library; +import 'dart:async'; import 'dart:js_interop'; import 'dart:js_interop_unsafe'; @@ -36,6 +37,94 @@ void main() { expect(firstResult, cachedResult); expect(secondResult, cachedResult); }); + + test('sets the JS SDK name for native JS errors', () async { + final sut = await fixture.getSut(); + sut.init({'dsn': fakeDsn}); + + const expectedMessage = 'native js captureException error'; + final client = _getClient(); + if (client == null) { + throw StateError('Sentry client is not registered'); + } + + final interceptedEvent = Completer>(); + void completeFailure(String message) { + if (!interceptedEvent.isCompleted) { + interceptedEvent.completeError(StateError(message)); + } + } + + final JSFunction beforeSendEventCallback = ((JSAny? event, JSAny? _) { + if (interceptedEvent.isCompleted) { + return; + } + if (event == null) { + completeFailure('beforeSendEvent callback received a null event.'); + return; + } + if (!event.isA()) { + completeFailure( + 'beforeSendEvent callback received a non-JSObject event.'); + return; + } + + final eventMap = (event as JSObject).dartify() as Map; + final exception = eventMap['exception']; + if (exception is! Map) { + completeFailure( + "beforeSendEvent event is missing an 'exception' map."); + return; + } + + final values = exception['values']; + if (values is! List || values.isEmpty) { + completeFailure( + "beforeSendEvent event exception map is missing a non-empty 'values' list."); + return; + } + + final firstValue = values.first; + if (firstValue is! Map) { + completeFailure( + "beforeSendEvent event exception values first item is not a map."); + return; + } + + final value = firstValue['value']; + if (value == null) { + completeFailure( + "beforeSendEvent event is missing exception 'value'."); + return; + } + + if (!value.toString().contains(expectedMessage)) { + completeFailure( + "beforeSendEvent exception value does not contain '$expectedMessage'. Actual: '$value'", + ); + return; + } + + interceptedEvent.complete(eventMap); + }).toJS; + client.on('beforeSendEvent'.toJS, beforeSendEventCallback); + + final sentry = _globalThis['Sentry'] as JSObject?; + final jsError = + _globalThis.callMethod('Error'.toJS, expectedMessage.toJS); + sentry!.callMethod('captureException'.toJS, jsError); + + final processedEvent = + await interceptedEvent.future.timeout(const Duration(seconds: 5)); + final sdk = processedEvent['sdk'] as Map?; + final exception = processedEvent['exception'] as Map?; + final values = exception?['values'] as List?; + final firstValue = values?.first as Map?; + + expect(sdk, isNotNull); + expect(sdk!['name'], jsSdkName); + expect(firstValue?['value'], contains(expectedMessage)); + }); }); } @@ -51,3 +140,16 @@ class Fixture { @JS('globalThis') external JSObject get _globalThis; + +@JS('Sentry.getClient') +external SentryJsClient? _getClient(); + +@JS() +@staticInterop +class SentryJsClient { + external factory SentryJsClient(); +} + +extension _SentryJsClientExtension on SentryJsClient { + external void on(JSString event, JSFunction callback); +} From 7022813deacf3683ae709ef5312cb5ac251a81cc Mon Sep 17 00:00:00 2001 From: buenaflor <23364143+buenaflor@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:05:08 +0000 Subject: [PATCH 62/62] release: 9.14.0 --- CHANGELOG.md | 2 +- docs/sdk-versions.md | 1 + packages/dart/lib/src/version.dart | 2 +- packages/dart/pubspec.yaml | 2 +- packages/dio/lib/src/version.dart | 2 +- packages/dio/pubspec.yaml | 4 ++-- packages/drift/lib/src/version.dart | 2 +- packages/drift/pubspec.yaml | 4 ++-- packages/file/lib/src/version.dart | 2 +- packages/file/pubspec.yaml | 4 ++-- packages/firebase_remote_config/pubspec.yaml | 4 ++-- packages/flutter/example/pubspec.yaml | 2 +- packages/flutter/lib/src/version.dart | 2 +- packages/flutter/pubspec.yaml | 4 ++-- packages/hive/lib/src/version.dart | 2 +- packages/hive/pubspec.yaml | 4 ++-- packages/isar/lib/src/version.dart | 2 +- packages/isar/pubspec.yaml | 4 ++-- packages/link/pubspec.yaml | 4 ++-- packages/logging/lib/src/version.dart | 2 +- packages/logging/pubspec.yaml | 4 ++-- packages/sqflite/lib/src/version.dart | 2 +- packages/sqflite/pubspec.yaml | 4 ++-- packages/supabase/pubspec.yaml | 4 ++-- 24 files changed, 35 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 818e456455..f4b3fc5f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 9.14.0 ### Features diff --git a/docs/sdk-versions.md b/docs/sdk-versions.md index a07d129d53..c860d80158 100644 --- a/docs/sdk-versions.md +++ b/docs/sdk-versions.md @@ -6,6 +6,7 @@ This document shows which version of the various Sentry SDKs are used in which S | Sentry Flutter SDK | Sentry Android SDK | Sentry Cocoa SDK | Sentry JavaScript SDK | Sentry Native SDK | | ------------------ | ------------------ | ---------------- | --------------------- | ----------------- | +| 9.14.0 | 8.33.0 | 8.56.2 | 10.38.0 | 0.12.8 | | 9.13.0 | 8.32.0 | 8.56.2 | 10.38.0 | 0.12.6 | | 9.12.0 | 8.31.0 | 8.56.2 | 10.6.0 | 0.12.5 | | 9.11.0 | 8.30.0 | 8.56.2 | 10.6.0 | 0.12.3 | diff --git a/packages/dart/lib/src/version.dart b/packages/dart/lib/src/version.dart index 41bf5a924c..e7364dcc1d 100644 --- a/packages/dart/lib/src/version.dart +++ b/packages/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index a29d4df18f..94e8f7975c 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 9.13.0 +version: 9.14.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/packages/dio/lib/src/version.dart b/packages/dio/lib/src/version.dart index b4e3f3af5b..19ec9a6f2a 100644 --- a/packages/dio/lib/src/version.dart +++ b/packages/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/packages/dio/pubspec.yaml b/packages/dio/pubspec.yaml index db7eeb17d2..8b52cb0a18 100644 --- a/packages/dio/pubspec.yaml +++ b/packages/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.2.0 - sentry: 9.13.0 + sentry: 9.14.0 dev_dependencies: meta: ^1.3.0 diff --git a/packages/drift/lib/src/version.dart b/packages/drift/lib/src/version.dart index 005f46fc3a..a3e7bcb85d 100644 --- a/packages/drift/lib/src/version.dart +++ b/packages/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/packages/drift/pubspec.yaml b/packages/drift/pubspec.yaml index 5255cd7222..f402909cf5 100644 --- a/packages/drift/pubspec.yaml +++ b/packages/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.13.0 + sentry: 9.14.0 meta: ^1.3.0 drift: ^2.24.0 diff --git a/packages/file/lib/src/version.dart b/packages/file/lib/src/version.dart index 6b074bf411..aeb917c4da 100644 --- a/packages/file/lib/src/version.dart +++ b/packages/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/packages/file/pubspec.yaml b/packages/file/pubspec.yaml index a4f5a845cd..df4b4ef86b 100644 --- a/packages/file/pubspec.yaml +++ b/packages/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 9.13.0 + sentry: 9.14.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/pubspec.yaml index 1867defc2e..4ceffe0c22 100644 --- a/packages/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_firebase_remote_config description: "Sentry integration to use feature flags from Firebase Remote Config." -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter firebase_remote_config: '>=5.4.3 <7.0.0' - sentry: 9.13.0 + sentry: 9.14.0 dev_dependencies: flutter_test: diff --git a/packages/flutter/example/pubspec.yaml b/packages/flutter/example/pubspec.yaml index e68d072b0a..ecbc240b82 100644 --- a/packages/flutter/example/pubspec.yaml +++ b/packages/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 9.13.0 +version: 9.14.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/packages/flutter/lib/src/version.dart b/packages/flutter/lib/src/version.dart index 7229002934..1dd5d7c479 100644 --- a/packages/flutter/lib/src/version.dart +++ b/packages/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index e88ec96eac..9b5f3fd9f0 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 9.13.0 +version: 9.14.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 9.13.0 + sentry: 9.14.0 package_info_plus: '>=1.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/packages/hive/lib/src/version.dart b/packages/hive/lib/src/version.dart index 012013cb34..e9735bf0ba 100644 --- a/packages/hive/lib/src/version.dart +++ b/packages/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/packages/hive/pubspec.yaml b/packages/hive/pubspec.yaml index 265f4aa5af..49e502bdcf 100644 --- a/packages/hive/pubspec.yaml +++ b/packages/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 9.13.0 + sentry: 9.14.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/packages/isar/lib/src/version.dart b/packages/isar/lib/src/version.dart index ed8f085fd8..07d769b88f 100644 --- a/packages/isar/lib/src/version.dart +++ b/packages/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/packages/isar/pubspec.yaml b/packages/isar/pubspec.yaml index b283356611..d554aa804b 100644 --- a/packages/isar/pubspec.yaml +++ b/packages/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 9.13.0 + sentry: 9.14.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/packages/link/pubspec.yaml b/packages/link/pubspec.yaml index d37b48a2bd..381c841073 100644 --- a/packages/link/pubspec.yaml +++ b/packages/link/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_link description: Automatic capture of exceptions and GraphQL errors for the gql eco-system, like graphql and ferry -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -13,7 +13,7 @@ dependencies: gql_exec: ">=0.4.4 <2.0.0" gql_link: ">=0.5.0 <2.0.0" gql: ">=0.14.0 <2.0.0" - sentry: 9.13.0 + sentry: 9.14.0 dev_dependencies: lints: ^4.0.0 diff --git a/packages/logging/lib/src/version.dart b/packages/logging/lib/src/version.dart index bddcb3a066..2e2a8493c3 100644 --- a/packages/logging/lib/src/version.dart +++ b/packages/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/packages/logging/pubspec.yaml b/packages/logging/pubspec.yaml index ff8f2a106b..be8fd5ed49 100644 --- a/packages/logging/pubspec.yaml +++ b/packages/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 9.13.0 + sentry: 9.14.0 meta: ^1.3.0 dev_dependencies: diff --git a/packages/sqflite/lib/src/version.dart b/packages/sqflite/lib/src/version.dart index 5df8459473..485921a4bb 100644 --- a/packages/sqflite/lib/src/version.dart +++ b/packages/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '9.13.0'; +const String sdkVersion = '9.14.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/packages/sqflite/pubspec.yaml b/packages/sqflite/pubspec.yaml index 43471cf92b..45862e5564 100644 --- a/packages/sqflite/pubspec.yaml +++ b/packages/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 9.13.0 + sentry: 9.14.0 sqflite: ^2.2.8 sqflite_common: ^2.0.0 meta: ^1.3.0 diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index adc308984f..b4d980a888 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_supabase description: "Sentry integration for Supabase. Adds performance tracing, breadcrumbs, and error capturing for Supabase database operations in Dart apps." -version: 9.13.0 +version: 9.14.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -11,7 +11,7 @@ environment: dependencies: http: ^1.3.0 meta: ^1.3.0 - sentry: 9.13.0 + sentry: 9.14.0 dev_dependencies: supabase: ^2.6.0