| // Copyright 2014 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| part of 'reporting.dart'; | |
| /// A generic usage even that does not involve custom dimensions. | |
| /// | |
| /// If sending values for custom dimensions is required, extend this class as | |
| /// below. | |
| class UsageEvent { | |
| UsageEvent(this.category, this.parameter, {this.label, this.value, required this.flutterUsage}); | |
| final String category; | |
| final String parameter; | |
| final String? label; | |
| final int? value; | |
| final Usage flutterUsage; | |
| void send() { | |
| flutterUsage.sendEvent(category, parameter, label: label, value: value); | |
| } | |
| } | |
| /// A usage event related to hot reload/restart. | |
| /// | |
| /// On a successful hot reload, we collect stats that help understand scale of | |
| /// the update. For example, [syncedLibraryCount]/[finalLibraryCount] indicates | |
| /// how many libraries were affected by the hot reload request. Relation of | |
| /// [invalidatedSourcesCount] to [syncedLibraryCount] should help understand | |
| /// sync/transfer "overhead" of updating this number of source files. | |
| class HotEvent extends UsageEvent { | |
| HotEvent( | |
| String parameter, { | |
| required this.targetPlatform, | |
| required this.sdkName, | |
| required this.emulator, | |
| required this.fullRestart, | |
| this.reason, | |
| this.finalLibraryCount, | |
| this.syncedLibraryCount, | |
| this.syncedClassesCount, | |
| this.syncedProceduresCount, | |
| this.syncedBytes, | |
| this.invalidatedSourcesCount, | |
| this.transferTimeInMs, | |
| this.overallTimeInMs, | |
| this.compileTimeInMs, | |
| this.findInvalidatedTimeInMs, | |
| this.scannedSourcesCount, | |
| this.reassembleTimeInMs, | |
| this.reloadVMTimeInMs, | |
| // TODO(fujino): make this required | |
| Usage? usage, | |
| }) : super('hot', parameter, flutterUsage: usage ?? globals.flutterUsage); | |
| final String? reason; | |
| final String targetPlatform; | |
| final String sdkName; | |
| final bool emulator; | |
| final bool fullRestart; | |
| final int? finalLibraryCount; | |
| final int? syncedLibraryCount; | |
| final int? syncedClassesCount; | |
| final int? syncedProceduresCount; | |
| final int? syncedBytes; | |
| final int? invalidatedSourcesCount; | |
| final int? transferTimeInMs; | |
| final int? overallTimeInMs; | |
| final int? compileTimeInMs; | |
| final int? findInvalidatedTimeInMs; | |
| final int? scannedSourcesCount; | |
| final int? reassembleTimeInMs; | |
| final int? reloadVMTimeInMs; | |
| @override | |
| void send() { | |
| final parameters = CustomDimensions( | |
| hotEventTargetPlatform: targetPlatform, | |
| hotEventSdkName: sdkName, | |
| hotEventEmulator: emulator, | |
| hotEventFullRestart: fullRestart, | |
| hotEventReason: reason, | |
| hotEventFinalLibraryCount: finalLibraryCount, | |
| hotEventSyncedLibraryCount: syncedLibraryCount, | |
| hotEventSyncedClassesCount: syncedClassesCount, | |
| hotEventSyncedProceduresCount: syncedProceduresCount, | |
| hotEventSyncedBytes: syncedBytes, | |
| hotEventInvalidatedSourcesCount: invalidatedSourcesCount, | |
| hotEventTransferTimeInMs: transferTimeInMs, | |
| hotEventOverallTimeInMs: overallTimeInMs, | |
| hotEventCompileTimeInMs: compileTimeInMs, | |
| hotEventFindInvalidatedTimeInMs: findInvalidatedTimeInMs, | |
| hotEventScannedSourcesCount: scannedSourcesCount, | |
| hotEventReassembleTimeInMs: reassembleTimeInMs, | |
| hotEventReloadVMTimeInMs: reloadVMTimeInMs, | |
| ); | |
| flutterUsage.sendEvent(category, parameter, parameters: parameters); | |
| } | |
| } | |
| /// An event that reports the result of a [DoctorValidator] | |
| class DoctorResultEvent extends UsageEvent { | |
| DoctorResultEvent({required this.validator, required this.result, Usage? flutterUsage}) | |
| : super( | |
| 'doctor-result', | |
| '${validator.runtimeType}', | |
| label: result.typeStr, | |
| flutterUsage: flutterUsage ?? globals.flutterUsage, | |
| ); | |
| final DoctorValidator validator; | |
| final ValidationResult result; | |
| @override | |
| void send() { | |
| if (validator is! GroupedValidator) { | |
| flutterUsage.sendEvent(category, parameter, label: label); | |
| return; | |
| } | |
| final group = validator as GroupedValidator; | |
| // The validator crashed. | |
| if (group.subResults.isEmpty) { | |
| flutterUsage.sendEvent(category, parameter, label: label); | |
| return; | |
| } | |
| for (var i = 0; i < group.subValidators.length; i++) { | |
| final DoctorValidator v = group.subValidators[i]; | |
| final ValidationResult r = group.subResults[i]; | |
| DoctorResultEvent(validator: v, result: r, flutterUsage: flutterUsage).send(); | |
| } | |
| } | |
| } | |
| /// An event that reports on the result of a pub invocation. | |
| class PubResultEvent extends UsageEvent { | |
| PubResultEvent({required String context, required String result, required Usage usage}) | |
| : super('pub-result', context, label: result, flutterUsage: usage); | |
| } | |
| /// An event that reports something about a build. | |
| class BuildEvent extends UsageEvent { | |
| BuildEvent( | |
| String label, { | |
| String? command, | |
| String? settings, | |
| String? eventError, | |
| required super.flutterUsage, | |
| required String type, | |
| }) : _command = command, | |
| _settings = settings, | |
| _eventError = eventError, | |
| super( | |
| // category | |
| 'build', | |
| // parameter | |
| type, | |
| label: label, | |
| ); | |
| final String? _command; | |
| final String? _settings; | |
| final String? _eventError; | |
| @override | |
| void send() { | |
| final parameters = CustomDimensions( | |
| buildEventCommand: _command, | |
| buildEventSettings: _settings, | |
| buildEventError: _eventError, | |
| ); | |
| flutterUsage.sendEvent(category, parameter, label: label, parameters: parameters); | |
| } | |
| } | |
| /// An event that reports the result of a top-level command. | |
| class CommandResultEvent extends UsageEvent { | |
| CommandResultEvent(super.commandPath, super.result, int? maxRss) | |
| : _maxRss = maxRss, | |
| super(flutterUsage: globals.flutterUsage); | |
| final int? _maxRss; | |
| @override | |
| void send() { | |
| // An event for the command result. | |
| flutterUsage.sendEvent('tool-command-result', category, label: parameter); | |
| // A separate event for the memory highwater mark. This is a separate event | |
| // so that we can get the command result even if trying to grab maxRss | |
| // throws an exception. | |
| if (_maxRss != null) { | |
| flutterUsage.sendEvent('tool-command-max-rss', category, label: parameter, value: _maxRss); | |
| } | |
| } | |
| } | |
| /// An event that reports on changes in the configuration of analytics. | |
| class AnalyticsConfigEvent extends UsageEvent { | |
| AnalyticsConfigEvent({ | |
| /// Whether analytics reporting is being enabled (true) or disabled (false). | |
| required bool enabled, | |
| }) : super( | |
| 'analytics', | |
| 'enabled', | |
| label: enabled ? 'true' : 'false', | |
| flutterUsage: globals.flutterUsage, | |
| ); | |
| } | |
| /// An event that reports when the code size measurement is run via `--analyze-size`. | |
| class CodeSizeEvent extends UsageEvent { | |
| CodeSizeEvent(String platform, {required super.flutterUsage}) | |
| : super('code-size-analysis', platform); | |
| } | |
| /// An event for tracking the usage of specific error handling fallbacks. | |
| class ErrorHandlingEvent extends UsageEvent { | |
| ErrorHandlingEvent(String parameter) | |
| : super('error-handling', parameter, flutterUsage: globals.flutterUsage); | |
| } |