Skip to content

Commit f3ec9ba

Browse files
committed
Add report view hierarchy identifier option
1 parent 0e12dac commit f3ec9ba

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

flutter/lib/src/sentry_flutter_options.dart

+4
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ class SentryFlutterOptions extends SentryOptions {
213213
@experimental
214214
bool attachViewHierarchy = false;
215215

216+
/// Enables reporting information of identifiers of the view hierarchy.
217+
/// This might contain sensitive information.
218+
bool reportViewHierarchyIdentifiers = true;
219+
216220
/// When enabled, the SDK tracks when the application stops responding for a
217221
/// specific amount of time, See [appHangTimeoutInterval].
218222
/// Only available on iOS and macOS.

flutter/lib/src/view_hierarchy/sentry_tree_walker.dart

+11-4
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ import '../widget_utils.dart';
209209
class _TreeWalker {
210210
static const _privateDelimiter = '_';
211211

212-
_TreeWalker(this.rootElement);
212+
_TreeWalker(this.rootElement, this.options);
213213

214214
final Element rootElement;
215+
final SentryFlutterOptions options;
215216

216217
ValueChanged<Element> _visitor(
217218
SentryViewHierarchyElement parentSentryElement) {
@@ -278,10 +279,15 @@ class _TreeWalker {
278279
alpha = widget.opacity;
279280
}
280281

282+
String? identifier;
283+
if (options.reportViewHierarchyIdentifiers) {
284+
identifier = WidgetUtils.toStringValue(widget.key);
285+
}
286+
281287
return SentryViewHierarchyElement(
282288
element.widget.runtimeType.toString(),
283289
depth: element.depth,
284-
identifier: WidgetUtils.toStringValue(element.widget.key),
290+
identifier: identifier,
285291
width: width,
286292
height: height,
287293
x: x,
@@ -292,15 +298,16 @@ class _TreeWalker {
292298
}
293299
}
294300

295-
SentryViewHierarchy? walkWidgetTree(WidgetsBinding instance) {
301+
SentryViewHierarchy? walkWidgetTree(
302+
WidgetsBinding instance, SentryFlutterOptions options) {
296303
// to keep compatibility with older versions
297304
// ignore: deprecated_member_use
298305
final rootElement = instance.renderViewElement;
299306
if (rootElement == null) {
300307
return null;
301308
}
302309

303-
final walker = _TreeWalker(rootElement);
310+
final walker = _TreeWalker(rootElement, options);
304311

305312
return walker.toSentryViewHierarchy();
306313
}

flutter/lib/src/view_hierarchy/view_hierarchy_event_processor.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class SentryViewHierarchyEventProcessor implements EventProcessor {
2323
if (instance == null) {
2424
return event;
2525
}
26-
final sentryViewHierarchy = walkWidgetTree(instance);
26+
final sentryViewHierarchy = walkWidgetTree(instance, _options);
2727

2828
if (sentryViewHierarchy == null) {
2929
return event;

flutter/test/view_hierarchy/view_hierarchy_event_processor_test.dart

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:convert';
2+
13
import 'package:flutter/material.dart';
24
import 'package:flutter_test/flutter_test.dart';
35
import 'package:sentry/sentry.dart';
@@ -79,6 +81,27 @@ void main() {
7981
expect(hint.viewHierarchy, isNull);
8082
});
8183
});
84+
85+
testWidgets('does not add view hierarchy identifiers if opt out in options',
86+
(tester) async {
87+
await tester.runAsync(() async {
88+
final sut =
89+
fixture.getSut(instance, reportViewHierarchyIdentifiers: false);
90+
91+
await tester.pumpWidget(MyApp());
92+
93+
final event = SentryEvent(
94+
exceptions: [SentryException(type: 'type', value: 'value')]);
95+
final hint = Hint();
96+
97+
sut.apply(event, hint);
98+
99+
expect(hint.viewHierarchy, isNotNull);
100+
final bytes = await hint.viewHierarchy!.bytes;
101+
final jsonString = utf8.decode(bytes);
102+
expect(jsonString, isNot(contains('identifier')));
103+
});
104+
});
82105
});
83106
}
84107

@@ -99,9 +122,11 @@ class TestBindingWrapper implements BindingWrapper {
99122
}
100123

101124
class Fixture {
102-
SentryViewHierarchyEventProcessor getSut(WidgetsBinding instance) {
125+
SentryViewHierarchyEventProcessor getSut(WidgetsBinding instance,
126+
{bool reportViewHierarchyIdentifiers = true}) {
103127
final options = SentryFlutterOptions()
104-
..bindingUtils = TestBindingWrapper(instance);
128+
..bindingUtils = TestBindingWrapper(instance)
129+
..reportViewHierarchyIdentifiers = reportViewHierarchyIdentifiers;
105130
return SentryViewHierarchyEventProcessor(options);
106131
}
107132
}

0 commit comments

Comments
 (0)