Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit c80ff45

Browse files
authored
Print events and views when first frame is taking awhile during tracing (#98957)
1 parent 82bd97c commit c80ff45

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

packages/flutter_tools/lib/src/tracing.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ class Tracing {
5151
// It is safe to ignore this error because we expect an error to be
5252
// thrown if we're already subscribed.
5353
}
54+
final StringBuffer bufferedEvents = StringBuffer();
55+
void Function(String) handleBufferedEvent = bufferedEvents.writeln;
5456
vmService.service.onExtensionEvent.listen((vm_service.Event event) {
57+
handleBufferedEvent('${event.extensionKind}: ${event.extensionData}');
5558
if (event.extensionKind == 'Flutter.FirstFrame') {
5659
whenFirstFrameRendered.complete();
5760
}
@@ -69,7 +72,19 @@ class Tracing {
6972
}
7073
}
7174
if (!done) {
75+
final Timer timer = Timer(const Duration(seconds: 10), () {
76+
_logger.printStatus('First frame is taking longer than expected...');
77+
_logger.printTrace('Views:');
78+
for (final FlutterView view in views) {
79+
_logger.printTrace('id: ${view.id} isolate: ${view.uiIsolate?.id}');
80+
}
81+
_logger.printTrace('Received VM events:');
82+
_logger.printTrace(bufferedEvents.toString());
83+
// Swap to just printing new events instead of buffering.
84+
handleBufferedEvent = _logger.printTrace;
85+
});
7286
await whenFirstFrameRendered.future;
87+
timer.cancel();
7388
}
7489
// The exception is rethrown, so don't catch only Exceptions.
7590
} catch (exception) { // ignore: avoid_catches_without_on_clauses

packages/flutter_tools/test/general.shard/tracing_test.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:async';
6+
7+
import 'package:fake_async/fake_async.dart';
58
import 'package:file/memory.dart';
69
import 'package:file_testing/file_testing.dart';
710
import 'package:flutter_tools/src/base/file_system.dart';
@@ -181,6 +184,58 @@ void main() {
181184
), throwsToolExit(message: 'Engine start event is missing in the timeline'));
182185
});
183186

187+
testWithoutContext('prints when first frame is taking a long time', () async {
188+
final BufferLogger logger = BufferLogger.test();
189+
final FileSystem fileSystem = MemoryFileSystem.test();
190+
final Completer<void> completer = Completer<void>();
191+
await FakeAsync().run((FakeAsync time) {
192+
final Map<String, String> extensionData = <String, String>{
193+
'test': 'data',
194+
'renderedErrorText': 'error text',
195+
};
196+
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
197+
const FakeVmServiceRequest(
198+
method: 'streamListen',
199+
args: <String, Object>{
200+
'streamId': vm_service.EventKind.kExtension,
201+
}
202+
),
203+
const FakeVmServiceRequest(
204+
method: kListViewsMethod,
205+
jsonResponse: <String, Object>{
206+
'views': <Object>[
207+
<String, Object?>{
208+
'id': '1',
209+
// No isolate, no views.
210+
'isolate': null,
211+
}
212+
],
213+
},
214+
),
215+
FakeVmServiceStreamResponse(
216+
streamId: 'Extension',
217+
event: vm_service.Event(
218+
timestamp: 0,
219+
extensionKind: 'Flutter.Error',
220+
extensionData: vm_service.ExtensionData.parse(extensionData),
221+
kind: vm_service.EventStreams.kExtension,
222+
),
223+
),
224+
]);
225+
unawaited(downloadStartupTrace(fakeVmServiceHost.vmService,
226+
output: fileSystem.currentDirectory,
227+
logger: logger,
228+
));
229+
time.elapse(const Duration(seconds: 11));
230+
time.flushMicrotasks();
231+
completer.complete();
232+
return completer.future;
233+
});
234+
expect(logger.statusText, contains('First frame is taking longer than expected'));
235+
expect(logger.traceText, contains('id: 1 isolate: null'));
236+
expect(logger.traceText, contains('Flutter.Error: [ExtensionData {test: data, renderedErrorText: error text}]'));
237+
});
238+
184239
testWithoutContext('throws tool exit if first frame events are missing', () async {
185240
final BufferLogger logger = BufferLogger.test();
186241
final FileSystem fileSystem = MemoryFileSystem.test();

0 commit comments

Comments
 (0)