| // 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 Usage flutterUsage, |
| required String type, |
| }) : _command = command, |
| _settings = settings, |
| _eventError = eventError, |
| super( |
| // category |
| 'build', |
| // parameter |
| type, |
| label: label, |
| flutterUsage: flutterUsage, |
| ); |
| |
| 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 Usage flutterUsage}) |
| : super('code-size-analysis', platform, flutterUsage: flutterUsage); |
| } |
| |
| /// 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); |
| } |