Skip to content

Commit

Permalink
Merge branch 'v7.0.0' into feat/before-send-transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto authored Feb 8, 2023
2 parents b76b18e + e6cb627 commit cb25b6a
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- Support beforeSendTransaction ([#1238](https://github.com/getsentry/sentry-dart/pull/1238))
- Add In Foreground to App context ([#1260](https://github.com/getsentry/sentry-dart/pull/1260))

### Fixes

Expand Down
10 changes: 10 additions & 0 deletions dart/lib/src/protocol/sentry_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SentryApp {
this.startTime,
this.deviceAppHash,
this.appMemory,
this.inForeground,
});

/// Human readable application name, as it appears on the platform.
Expand All @@ -43,6 +44,10 @@ class SentryApp {
/// Amount of memory used by the application in bytes.
final int? appMemory;

/// A flag indicating whether the app is in foreground or not.
/// An app is in foreground when it's visible to the user.
final bool? inForeground;

/// Deserializes a [SentryApp] from JSON [Map].
factory SentryApp.fromJson(Map<String, dynamic> data) => SentryApp(
name: data['app_name'],
Expand All @@ -55,6 +60,7 @@ class SentryApp {
: null,
deviceAppHash: data['device_app_hash'],
appMemory: data['app_memory'],
inForeground: data['in_foreground'],
);

/// Produces a [Map] that can be serialized to JSON.
Expand All @@ -68,6 +74,7 @@ class SentryApp {
if (deviceAppHash != null) 'device_app_hash': deviceAppHash!,
if (appMemory != null) 'app_memory': appMemory!,
if (startTime != null) 'app_start_time': startTime!.toIso8601String(),
if (inForeground != null) 'in_foreground': inForeground!,
};
}

Expand All @@ -80,6 +87,7 @@ class SentryApp {
startTime: startTime,
deviceAppHash: deviceAppHash,
appMemory: appMemory,
inForeground: inForeground,
);

SentryApp copyWith({
Expand All @@ -91,6 +99,7 @@ class SentryApp {
DateTime? startTime,
String? deviceAppHash,
int? appMemory,
bool? inForeground,
}) =>
SentryApp(
name: name ?? this.name,
Expand All @@ -101,5 +110,6 @@ class SentryApp {
startTime: startTime ?? this.startTime,
deviceAppHash: deviceAppHash ?? this.deviceAppHash,
appMemory: appMemory ?? this.appMemory,
inForeground: inForeground ?? this.inForeground,
);
}
21 changes: 13 additions & 8 deletions dart/test/protocol/sentry_app_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ void main() {
final testStartTime = DateTime.fromMicrosecondsSinceEpoch(0);

final sentryApp = SentryApp(
name: 'fixture-name',
version: 'fixture-version',
identifier: 'fixture-identifier',
build: 'fixture-build',
buildType: 'fixture-buildType',
startTime: testStartTime,
deviceAppHash: 'fixture-deviceAppHash');
name: 'fixture-name',
version: 'fixture-version',
identifier: 'fixture-identifier',
build: 'fixture-build',
buildType: 'fixture-buildType',
startTime: testStartTime,
deviceAppHash: 'fixture-deviceAppHash',
inForeground: true,
);

final sentryAppJson = <String, dynamic>{
'app_name': 'fixture-name',
Expand All @@ -21,7 +23,8 @@ void main() {
'app_build': 'fixture-build',
'build_type': 'fixture-buildType',
'app_start_time': testStartTime.toIso8601String(),
'device_app_hash': 'fixture-deviceAppHash'
'device_app_hash': 'fixture-deviceAppHash',
'in_foreground': true,
};

group('json', () {
Expand Down Expand Up @@ -69,6 +72,7 @@ void main() {
buildType: 'buildType1',
startTime: startTime,
deviceAppHash: 'hash1',
inForeground: true,
);

expect('name1', copy.name);
Expand All @@ -78,6 +82,7 @@ void main() {
expect('buildType1', copy.buildType);
expect(startTime, copy.startTime);
expect('hash1', copy.deviceAppHash);
expect(true, copy.inForeground);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class FlutterEnricherEventProcessor extends EventProcessor {
runtimes: _getRuntimes(event.contexts.runtimes),
culture: _getCulture(event.contexts.culture),
operatingSystem: _getOperatingSystem(event.contexts.operatingSystem),
app: _getApp(event.contexts.app),
);

// Flutter has a lot of Accessibility Settings available and exposes them
Expand Down Expand Up @@ -217,4 +218,18 @@ class FlutterEnricherEventProcessor extends EventProcessor {
flutterRuntime,
];
}

SentryApp? _getApp(SentryApp? app) {
final currentLifecycle = _widgetsBinding?.lifecycleState;
if (currentLifecycle == null) {
return app;
}

// See 'flutter_context' for more detailed app state.
final inForeground = currentLifecycle == AppLifecycleState.resumed;

return (app ?? SentryApp()).copyWith(
inForeground: inForeground,
);
}
}
9 changes: 9 additions & 0 deletions flutter/lib/src/integrations/load_contexts_integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,21 @@ class _LoadContextsIntegrationEventProcessor extends EventProcessor {
} else if (currentValue == null) {
eventContexts[key] = value;
} else {
// merge the values
if (key == SentryOperatingSystem.type &&
currentValue is SentryOperatingSystem &&
value is SentryOperatingSystem) {
// merge os context
final osMap = {...value.toJson(), ...currentValue.toJson()};
final os = SentryOperatingSystem.fromJson(osMap);
eventContexts[key] = os;
} else if (key == SentryApp.type &&
currentValue is SentryApp &&
value is SentryApp) {
// merge app context
final appMap = {...value.toJson(), ...currentValue.toJson()};
final app = SentryApp.fromJson(appMap);
eventContexts[key] = app;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,51 @@ void main() {
expect(culture?.timezone, isNotNull);
});

testWidgets('app context in foreground', (WidgetTester tester) async {
final enricher = fixture.getSut(
binding: () => tester.binding,
);

tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed);
final event = await enricher.apply(SentryEvent());

final app = event.contexts.app;

expect(app?.inForeground, true);
});

testWidgets('app context not in foreground', (WidgetTester tester) async {
final enricher = fixture.getSut(
binding: () => tester.binding,
);

tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive);
final event = await enricher.apply(SentryEvent());

final app = event.contexts.app;

expect(app?.inForeground, false);
});

testWidgets('merge app context in foreground', (WidgetTester tester) async {
final enricher = fixture.getSut(
binding: () => tester.binding,
);

tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed);

const appName = 'My App';
final event = SentryEvent();
event.contexts.app = SentryApp(name: appName);

final mutatedEvent = await enricher.apply(event);

final app = mutatedEvent.contexts.app;

expect(app?.inForeground, true);
expect(app?.name, appName);
});

testWidgets('no device when native integration is available',
(WidgetTester tester) async {
final enricher = fixture.getSut(
Expand Down
35 changes: 20 additions & 15 deletions flutter/test/integrations/load_contexts_integrations_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,21 @@ void main() {
packages: packages);
}

SentryEvent getEvent(
{SdkVersion? sdk,
Map<String, String>? tags,
Map<String, dynamic>? extra,
SentryUser? user,
String? dist,
String? environment,
List<String>? fingerprint,
SentryLevel? level,
List<Breadcrumb>? breadcrumbs,
List<String> integrations = const ['EventIntegration'],
List<SentryPackage> packages = const [
SentryPackage('event-package', '2.0')
]}) {
SentryEvent getEvent({
SdkVersion? sdk,
Map<String, String>? tags,
Map<String, dynamic>? extra,
SentryUser? user,
String? dist,
String? environment,
List<String>? fingerprint,
SentryLevel? level,
List<Breadcrumb>? breadcrumbs,
List<String> integrations = const ['EventIntegration'],
List<SentryPackage> packages = const [
SentryPackage('event-package', '2.0')
],
}) {
return SentryEvent(
sdk: sdk ??
getSdkVersion(
Expand Down Expand Up @@ -77,11 +78,14 @@ void main() {

final e = SentryEvent();
e.contexts.operatingSystem = SentryOperatingSystem(theme: 'theme1');
e.contexts.app = SentryApp(inForeground: true);

final event = await fixture.options.eventProcessors.first.apply(e);

expect(fixture.called, true);
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');
Expand All @@ -107,7 +111,7 @@ void main() {

final eventContexts = Contexts(
device: const SentryDevice(name: 'eDevice'),
app: const SentryApp(name: 'eApp'),
app: const SentryApp(name: 'eApp', inForeground: true),
operatingSystem: const SentryOperatingSystem(name: 'eOS'),
gpu: const SentryGpu(name: 'eGpu'),
browser: const SentryBrowser(name: 'eBrowser'),
Expand All @@ -121,6 +125,7 @@ void main() {
expect(fixture.called, true);
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');
Expand Down

0 comments on commit cb25b6a

Please sign in to comment.