@@ -7,6 +7,7 @@ import 'dart:async';
7
7
import 'package:meta/meta.dart' ;
8
8
import 'package:package_config/package_config.dart' ;
9
9
import 'package:pool/pool.dart' ;
10
+ import 'package:unified_analytics/unified_analytics.dart' ;
10
11
import 'package:vm_service/vm_service.dart' as vm_service;
11
12
12
13
import 'base/context.dart' ;
@@ -94,17 +95,20 @@ class HotRunner extends ResidentRunner {
94
95
ReloadSourcesHelper reloadSourcesHelper = defaultReloadSourcesHelper,
95
96
ReassembleHelper reassembleHelper = _defaultReassembleHelper,
96
97
NativeAssetsBuildRunner ? buildRunner,
97
- }) : _stopwatchFactory = stopwatchFactory,
98
- _reloadSourcesHelper = reloadSourcesHelper,
99
- _reassembleHelper = reassembleHelper,
98
+ required Analytics analytics,
99
+ }) : _stopwatchFactory = stopwatchFactory,
100
+ _reloadSourcesHelper = reloadSourcesHelper,
101
+ _reassembleHelper = reassembleHelper,
100
102
_buildRunner = buildRunner,
101
- super (
103
+ _analytics = analytics,
104
+ super (
102
105
hotMode: true ,
103
106
);
104
107
105
108
final StopwatchFactory _stopwatchFactory;
106
109
final ReloadSourcesHelper _reloadSourcesHelper;
107
110
final ReassembleHelper _reassembleHelper;
111
+ final Analytics _analytics;
108
112
109
113
final bool benchmarkMode;
110
114
final File ? applicationBinary;
@@ -429,15 +433,29 @@ class HotRunner extends ResidentRunner {
429
433
}));
430
434
}
431
435
432
- unawaited (appStartedCompleter? .future.then ((_) => HotEvent ('reload-ready' ,
433
- targetPlatform: _targetPlatform! ,
434
- sdkName: _sdkName! ,
435
- emulator: _emulator! ,
436
- fullRestart: false ,
437
- overallTimeInMs: appStartedTimer.elapsed.inMilliseconds,
438
- compileTimeInMs: totalCompileTime.inMilliseconds,
439
- transferTimeInMs: totalLaunchAppTime.inMilliseconds,
440
- ).send ()));
436
+ unawaited (appStartedCompleter? .future.then ((_) {
437
+ HotEvent (
438
+ 'reload-ready' ,
439
+ targetPlatform: _targetPlatform! ,
440
+ sdkName: _sdkName! ,
441
+ emulator: _emulator! ,
442
+ fullRestart: false ,
443
+ overallTimeInMs: appStartedTimer.elapsed.inMilliseconds,
444
+ compileTimeInMs: totalCompileTime.inMilliseconds,
445
+ transferTimeInMs: totalLaunchAppTime.inMilliseconds,
446
+ ).send ();
447
+
448
+ _analytics.send (Event .hotRunnerInfo (
449
+ label: 'reload-ready' ,
450
+ targetPlatform: _targetPlatform! ,
451
+ sdkName: _sdkName! ,
452
+ emulator: _emulator! ,
453
+ fullRestart: false ,
454
+ overallTimeInMs: appStartedTimer.elapsed.inMilliseconds,
455
+ compileTimeInMs: totalCompileTime.inMilliseconds,
456
+ transferTimeInMs: totalLaunchAppTime.inMilliseconds,
457
+ ));
458
+ }));
441
459
442
460
try {
443
461
final List <bool > results = await Future .wait (startupTasks);
@@ -828,6 +846,21 @@ class HotRunner extends ResidentRunner {
828
846
findInvalidatedTimeInMs: result.updateFSReport? .findInvalidatedDuration.inMilliseconds,
829
847
scannedSourcesCount: result.updateFSReport? .scannedSourcesCount,
830
848
).send ();
849
+ _analytics.send (Event .hotRunnerInfo (
850
+ label: 'restart' ,
851
+ targetPlatform: targetPlatform,
852
+ sdkName: sdkName,
853
+ emulator: emulator,
854
+ fullRestart: true ,
855
+ reason: reason,
856
+ overallTimeInMs: restartTimer.elapsed.inMilliseconds,
857
+ syncedBytes: result.updateFSReport? .syncedBytes,
858
+ invalidatedSourcesCount: result.updateFSReport? .invalidatedSourcesCount,
859
+ transferTimeInMs: result.updateFSReport? .transferDuration.inMilliseconds,
860
+ compileTimeInMs: result.updateFSReport? .compileDuration.inMilliseconds,
861
+ findInvalidatedTimeInMs: result.updateFSReport? .findInvalidatedDuration.inMilliseconds,
862
+ scannedSourcesCount: result.updateFSReport? .scannedSourcesCount,
863
+ ));
831
864
}
832
865
} on vm_service.SentinelException catch (err, st) {
833
866
restartEvent = 'exception' ;
@@ -846,6 +879,14 @@ class HotRunner extends ResidentRunner {
846
879
fullRestart: true ,
847
880
reason: reason,
848
881
).send ();
882
+ _analytics.send (Event .hotRunnerInfo (
883
+ label: restartEvent,
884
+ targetPlatform: targetPlatform,
885
+ sdkName: sdkName,
886
+ emulator: emulator,
887
+ fullRestart: true ,
888
+ reason: reason,
889
+ ));
849
890
}
850
891
status? .cancel ();
851
892
}
@@ -895,6 +936,14 @@ class HotRunner extends ResidentRunner {
895
936
fullRestart: false ,
896
937
reason: reason,
897
938
).send ();
939
+ _analytics.send (Event .hotRunnerInfo (
940
+ label: 'reload-barred' ,
941
+ targetPlatform: targetPlatform,
942
+ sdkName: sdkName,
943
+ emulator: emulator,
944
+ fullRestart: false ,
945
+ reason: reason,
946
+ ));
898
947
} else {
899
948
HotEvent ('exception' ,
900
949
targetPlatform: targetPlatform! ,
@@ -903,6 +952,14 @@ class HotRunner extends ResidentRunner {
903
952
fullRestart: false ,
904
953
reason: reason,
905
954
).send ();
955
+ _analytics.send (Event .hotRunnerInfo (
956
+ label: 'exception' ,
957
+ targetPlatform: targetPlatform,
958
+ sdkName: sdkName,
959
+ emulator: emulator,
960
+ fullRestart: false ,
961
+ reason: reason,
962
+ ));
906
963
}
907
964
return OperationResult (errorCode, errorMessage, fatal: true );
908
965
} finally {
@@ -965,6 +1022,7 @@ class HotRunner extends ResidentRunner {
965
1022
emulator,
966
1023
reason,
967
1024
globals.flutterUsage,
1025
+ globals.analytics,
968
1026
);
969
1027
if (result.code != 0 ) {
970
1028
return result;
@@ -1024,6 +1082,27 @@ class HotRunner extends ResidentRunner {
1024
1082
reassembleTimeInMs: reassembleTimer.elapsed.inMilliseconds,
1025
1083
reloadVMTimeInMs: reloadVMTimer.elapsed.inMilliseconds,
1026
1084
).send ();
1085
+ _analytics.send (Event .hotRunnerInfo (
1086
+ label: 'reload' ,
1087
+ targetPlatform: targetPlatform,
1088
+ sdkName: sdkName,
1089
+ emulator: emulator,
1090
+ fullRestart: false ,
1091
+ reason: reason,
1092
+ overallTimeInMs: reloadInMs,
1093
+ finalLibraryCount: firstReloadDetails['finalLibraryCount' ] as int ? ?? 0 ,
1094
+ syncedLibraryCount: firstReloadDetails['receivedLibraryCount' ] as int ? ?? 0 ,
1095
+ syncedClassesCount: firstReloadDetails['receivedClassesCount' ] as int ? ?? 0 ,
1096
+ syncedProceduresCount: firstReloadDetails['receivedProceduresCount' ] as int ? ?? 0 ,
1097
+ syncedBytes: updatedDevFS.syncedBytes,
1098
+ invalidatedSourcesCount: updatedDevFS.invalidatedSourcesCount,
1099
+ transferTimeInMs: updatedDevFS.transferDuration.inMilliseconds,
1100
+ compileTimeInMs: updatedDevFS.compileDuration.inMilliseconds,
1101
+ findInvalidatedTimeInMs: updatedDevFS.findInvalidatedDuration.inMilliseconds,
1102
+ scannedSourcesCount: updatedDevFS.scannedSourcesCount,
1103
+ reassembleTimeInMs: reassembleTimer.elapsed.inMilliseconds,
1104
+ reloadVMTimeInMs: reloadVMTimer.elapsed.inMilliseconds,
1105
+ ));
1027
1106
1028
1107
if (shouldReportReloadTime) {
1029
1108
globals.printTrace ('Hot reload performed in ${getElapsedAsMilliseconds (reloadDuration )}.' );
@@ -1186,6 +1265,7 @@ typedef ReloadSourcesHelper = Future<OperationResult> Function(
1186
1265
bool ? emulator,
1187
1266
String ? reason,
1188
1267
Usage usage,
1268
+ Analytics analytics,
1189
1269
);
1190
1270
1191
1271
@visibleForTesting
@@ -1199,6 +1279,7 @@ Future<OperationResult> defaultReloadSourcesHelper(
1199
1279
bool ? emulator,
1200
1280
String ? reason,
1201
1281
Usage usage,
1282
+ Analytics analytics,
1202
1283
) async {
1203
1284
final Stopwatch vmReloadTimer = Stopwatch ()..start ();
1204
1285
const String entryPath = 'main.dart.incremental.dill' ;
@@ -1239,6 +1320,14 @@ Future<OperationResult> defaultReloadSourcesHelper(
1239
1320
reason: reason,
1240
1321
usage: usage,
1241
1322
).send ();
1323
+ analytics.send (Event .hotRunnerInfo (
1324
+ label: 'reload-reject' ,
1325
+ targetPlatform: targetPlatform,
1326
+ sdkName: sdkName,
1327
+ emulator: emulator,
1328
+ fullRestart: false ,
1329
+ reason: reason,
1330
+ ));
1242
1331
// Reset devFS lastCompileTime to ensure the file will still be marked
1243
1332
// as dirty on subsequent reloads.
1244
1333
_resetDevFSCompileTime (flutterDevices);
0 commit comments