Unverified Commit 2acd0007 authored by Lau Ching Jun's avatar Lau Ching Jun Committed by GitHub

Refactor CustomDimensions in analytics to be type safe (#82531)

parent 3b19dfd4
...@@ -140,20 +140,20 @@ class AssembleCommand extends FlutterCommand { ...@@ -140,20 +140,20 @@ class AssembleCommand extends FlutterCommand {
String get name => 'assemble'; String get name => 'assemble';
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
if (flutterProject == null) { if (flutterProject == null) {
return const <CustomDimensions, String>{}; return const CustomDimensions();
} }
try { try {
return <CustomDimensions, String>{ return CustomDimensions(
CustomDimensions.commandBuildBundleTargetPlatform: environment.defines[kTargetPlatform], commandBuildBundleTargetPlatform: environment.defines[kTargetPlatform],
CustomDimensions.commandBuildBundleIsModule: '${flutterProject.isModule}', commandBuildBundleIsModule: flutterProject.isModule,
}; );
} on Exception { } on Exception {
// We've failed to send usage. // We've failed to send usage.
} }
return const <CustomDimensions, String>{}; return const CustomDimensions();
} }
@override @override
......
...@@ -75,21 +75,25 @@ class BuildAarCommand extends BuildSubCommand { ...@@ -75,21 +75,25 @@ class BuildAarCommand extends BuildSubCommand {
}; };
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final Map<CustomDimensions, String> usage = <CustomDimensions, String>{};
final FlutterProject flutterProject = _getProject(); final FlutterProject flutterProject = _getProject();
if (flutterProject == null) { if (flutterProject == null) {
return usage; return const CustomDimensions();
} }
String projectType;
if (flutterProject.manifest.isModule) { if (flutterProject.manifest.isModule) {
usage[CustomDimensions.commandBuildAarProjectType] = 'module'; projectType = 'module';
} else if (flutterProject.manifest.isPlugin) { } else if (flutterProject.manifest.isPlugin) {
usage[CustomDimensions.commandBuildAarProjectType] = 'plugin'; projectType = 'plugin';
} else { } else {
usage[CustomDimensions.commandBuildAarProjectType] = 'app'; projectType = 'app';
} }
usage[CustomDimensions.commandBuildAarTargetPlatform] = stringsArg('target-platform').join(',');
return usage; return CustomDimensions(
commandBuildAarProjectType: projectType,
commandBuildAarTargetPlatform: stringsArg('target-platform').join(','),
);
} }
@override @override
......
...@@ -68,25 +68,25 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -68,25 +68,25 @@ class BuildApkCommand extends BuildSubCommand {
' * https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split'; ' * https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split';
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final Map<CustomDimensions, String> usage = <CustomDimensions, String>{}; String buildMode;
usage[CustomDimensions.commandBuildApkTargetPlatform] =
stringsArg('target-platform').join(',');
usage[CustomDimensions.commandBuildApkSplitPerAbi] =
boolArg('split-per-abi').toString();
if (boolArg('release')) { if (boolArg('release')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'release'; buildMode = 'release';
} else if (boolArg('debug')) { } else if (boolArg('debug')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'debug'; buildMode = 'debug';
} else if (boolArg('profile')) { } else if (boolArg('profile')) {
usage[CustomDimensions.commandBuildApkBuildMode] = 'profile'; buildMode = 'profile';
} else { } else {
// The build defaults to release. // The build defaults to release.
usage[CustomDimensions.commandBuildApkBuildMode] = 'release'; buildMode = 'release';
} }
return usage;
return CustomDimensions(
commandBuildApkTargetPlatform: stringsArg('target-platform').join(','),
commandBuildApkBuildMode: buildMode,
commandBuildApkSplitPerAbi: boolArg('split-per-abi'),
);
} }
@override @override
......
...@@ -82,23 +82,24 @@ class BuildAppBundleCommand extends BuildSubCommand { ...@@ -82,23 +82,24 @@ class BuildAppBundleCommand extends BuildSubCommand {
'suitable for deploying to app stores. \n app bundle improves your app size'; 'suitable for deploying to app stores. \n app bundle improves your app size';
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final Map<CustomDimensions, String> usage = <CustomDimensions, String>{}; String buildMode;
usage[CustomDimensions.commandBuildAppBundleTargetPlatform] =
stringsArg('target-platform').join(',');
if (boolArg('release')) { if (boolArg('release')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'release'; buildMode = 'release';
} else if (boolArg('debug')) { } else if (boolArg('debug')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'debug'; buildMode = 'debug';
} else if (boolArg('profile')) { } else if (boolArg('profile')) {
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'profile'; buildMode = 'profile';
} else { } else {
// The build defaults to release. // The build defaults to release.
usage[CustomDimensions.commandBuildAppBundleBuildMode] = 'release'; buildMode = 'release';
} }
return usage;
return CustomDimensions(
commandBuildAppBundleTargetPlatform: stringsArg('target-platform').join(','),
commandBuildAppBundleBuildMode: buildMode,
);
} }
@override @override
......
...@@ -69,16 +69,16 @@ class BuildBundleCommand extends BuildSubCommand { ...@@ -69,16 +69,16 @@ class BuildBundleCommand extends BuildSubCommand {
' iOS runtimes.'; ' iOS runtimes.';
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final String projectDir = globals.fs.file(targetFile).parent.parent.path; final String projectDir = globals.fs.file(targetFile).parent.parent.path;
final FlutterProject flutterProject = FlutterProject.fromDirectory(globals.fs.directory(projectDir)); final FlutterProject flutterProject = FlutterProject.fromDirectory(globals.fs.directory(projectDir));
if (flutterProject == null) { if (flutterProject == null) {
return const <CustomDimensions, String>{}; return const CustomDimensions();
} }
return <CustomDimensions, String>{ return CustomDimensions(
CustomDimensions.commandBuildBundleTargetPlatform: stringArg('target-platform'), commandBuildBundleTargetPlatform: stringArg('target-platform'),
CustomDimensions.commandBuildBundleIsModule: '${flutterProject.isModule}', commandBuildBundleIsModule: flutterProject.isModule,
}; );
} }
@override @override
......
...@@ -79,12 +79,12 @@ class CreateCommand extends CreateBase { ...@@ -79,12 +79,12 @@ class CreateCommand extends CreateBase {
String get invocation => '${runner.executableName} $name <output directory>'; String get invocation => '${runner.executableName} $name <output directory>';
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
return <CustomDimensions, String>{ return CustomDimensions(
CustomDimensions.commandCreateProjectType: stringArg('template'), commandCreateProjectType: stringArg('template'),
CustomDimensions.commandCreateAndroidLanguage: stringArg('android-language'), commandCreateAndroidLanguage: stringArg('android-language'),
CustomDimensions.commandCreateIosLanguage: stringArg('ios-language'), commandCreateIosLanguage: stringArg('ios-language'),
}; );
} }
// Lazy-initialize the net utilities with values from the context. // Lazy-initialize the net utilities with values from the context.
......
...@@ -81,13 +81,15 @@ class PackagesGetCommand extends FlutterCommand { ...@@ -81,13 +81,15 @@ class PackagesGetCommand extends FlutterCommand {
/// The pub packages usage values are incorrect since these are calculated/sent /// The pub packages usage values are incorrect since these are calculated/sent
/// before pub get completes. This needs to be performed after dependency resolution. /// before pub get completes. This needs to be performed after dependency resolution.
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
final Map<CustomDimensions, String> usageValues = <CustomDimensions, String>{};
final String workingDirectory = argResults.rest.length == 1 ? argResults.rest[0] : null; final String workingDirectory = argResults.rest.length == 1 ? argResults.rest[0] : null;
final String target = findProjectRoot(globals.fs, workingDirectory); final String target = findProjectRoot(globals.fs, workingDirectory);
if (target == null) { if (target == null) {
return usageValues; return const CustomDimensions();
} }
int numberPlugins;
final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target));
// Do not send plugin analytics if pub has not run before. // Do not send plugin analytics if pub has not run before.
final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync()
...@@ -97,14 +99,16 @@ class PackagesGetCommand extends FlutterCommand { ...@@ -97,14 +99,16 @@ class PackagesGetCommand extends FlutterCommand {
// Do not fail pub get if package config files are invalid before pub has // Do not fail pub get if package config files are invalid before pub has
// had a chance to run. // had a chance to run.
final List<Plugin> plugins = await findPlugins(rootProject, throwOnError: false); final List<Plugin> plugins = await findPlugins(rootProject, throwOnError: false);
usageValues[CustomDimensions.commandPackagesNumberPlugins] = plugins.length.toString(); numberPlugins = plugins.length;
} else { } else {
usageValues[CustomDimensions.commandPackagesNumberPlugins] = '0'; numberPlugins = 0;
} }
usageValues[CustomDimensions.commandPackagesProjectModule] = '${rootProject.isModule}';
usageValues[CustomDimensions.commandPackagesAndroidEmbeddingVersion] = return CustomDimensions(
rootProject.android.getEmbeddingVersion().toString().split('.').last; commandPackagesNumberPlugins: numberPlugins,
return usageValues; commandPackagesProjectModule: rootProject.isModule,
commandPackagesAndroidEmbeddingVersion: rootProject.android.getEmbeddingVersion().toString().split('.').last,
);
} }
Future<void> _runPubGet(String directory, FlutterProject flutterProject) async { Future<void> _runPubGet(String directory, FlutterProject flutterProject) async {
......
...@@ -357,7 +357,7 @@ class RunCommand extends RunCommandBase { ...@@ -357,7 +357,7 @@ class RunCommand extends RunCommandBase {
} }
@override @override
Future<Map<CustomDimensions, String>> get usageValues async { Future<CustomDimensions> get usageValues async {
String deviceType, deviceOsVersion; String deviceType, deviceOsVersion;
bool isEmulator; bool isEmulator;
bool anyAndroidDevices = false; bool anyAndroidDevices = false;
...@@ -410,16 +410,15 @@ class RunCommand extends RunCommandBase { ...@@ -410,16 +410,15 @@ class RunCommand extends RunCommandBase {
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo();
final String modeName = buildInfo.modeName; final String modeName = buildInfo.modeName;
return <CustomDimensions, String>{ return CustomDimensions(
CustomDimensions.commandRunIsEmulator: '$isEmulator', commandRunIsEmulator: isEmulator,
CustomDimensions.commandRunTargetName: deviceType, commandRunTargetName: deviceType,
CustomDimensions.commandRunTargetOsVersion: deviceOsVersion, commandRunTargetOsVersion: deviceOsVersion,
CustomDimensions.commandRunModeName: modeName, commandRunModeName: modeName,
CustomDimensions.commandRunProjectModule: '${FlutterProject.current().isModule}', commandRunProjectModule: FlutterProject.current().isModule,
CustomDimensions.commandRunProjectHostLanguage: hostLanguage.join(','), commandRunProjectHostLanguage: hostLanguage.join(','),
if (androidEmbeddingVersion != null) commandRunAndroidEmbeddingVersion: androidEmbeddingVersion,
CustomDimensions.commandRunAndroidEmbeddingVersion: androidEmbeddingVersion, );
};
} }
@override @override
......
// 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;
/// The collection of custom dimensions understood by the analytics backend.
/// When adding to this list, first ensure that the custom dimension is
/// defined in the backend, or will be defined shortly after the relevant PR
/// lands.
@immutable
class CustomDimensions {
const CustomDimensions({
this.sessionHostOsDetails,
this.sessionChannelName,
this.commandRunIsEmulator,
this.commandRunTargetName,
this.hotEventReason,
this.hotEventFinalLibraryCount,
this.hotEventSyncedLibraryCount,
this.hotEventSyncedClassesCount,
this.hotEventSyncedProceduresCount,
this.hotEventSyncedBytes,
this.hotEventInvalidatedSourcesCount,
this.hotEventTransferTimeInMs,
this.hotEventOverallTimeInMs,
this.commandRunProjectType,
this.commandRunProjectHostLanguage,
this.commandCreateAndroidLanguage,
this.commandCreateIosLanguage,
this.commandRunProjectModule,
this.commandCreateProjectType,
this.commandPackagesNumberPlugins,
this.commandPackagesProjectModule,
this.commandRunTargetOsVersion,
this.commandRunModeName,
this.commandBuildBundleTargetPlatform,
this.commandBuildBundleIsModule,
this.commandResult,
this.hotEventTargetPlatform,
this.hotEventSdkName,
this.hotEventEmulator,
this.hotEventFullRestart,
this.commandHasTerminal,
this.enabledFlutterFeatures,
this.localTime,
this.commandBuildAarTargetPlatform,
this.commandBuildAarProjectType,
this.buildEventCommand,
this.buildEventSettings,
this.commandBuildApkTargetPlatform,
this.commandBuildApkBuildMode,
this.commandBuildApkSplitPerAbi,
this.commandBuildAppBundleTargetPlatform,
this.commandBuildAppBundleBuildMode,
this.buildEventError,
this.commandResultEventMaxRss,
this.commandRunAndroidEmbeddingVersion,
this.commandPackagesAndroidEmbeddingVersion,
this.nullSafety,
this.fastReassemble,
this.nullSafeMigratedLibraries,
this.nullSafeTotalLibraries,
});
final String? sessionHostOsDetails; // cd1
final String? sessionChannelName; // cd2
final bool? commandRunIsEmulator; // cd3
final String? commandRunTargetName; // cd4
final String? hotEventReason; // cd5
final int? hotEventFinalLibraryCount; // cd6
final int? hotEventSyncedLibraryCount; // cd7
final int? hotEventSyncedClassesCount; // cd8
final int? hotEventSyncedProceduresCount; // cd9
final int? hotEventSyncedBytes; // cd10
final int? hotEventInvalidatedSourcesCount; // cd11
final int? hotEventTransferTimeInMs; // cd12
final int? hotEventOverallTimeInMs; // cd13
final String? commandRunProjectType; // cd14
final String? commandRunProjectHostLanguage; // cd15
final String? commandCreateAndroidLanguage; // cd16
final String? commandCreateIosLanguage; // cd17
final bool? commandRunProjectModule; // cd18
final String? commandCreateProjectType; // cd19
final int? commandPackagesNumberPlugins; // cd20
final bool? commandPackagesProjectModule; // cd21
final String? commandRunTargetOsVersion; // cd22
final String? commandRunModeName; // cd23
final String? commandBuildBundleTargetPlatform; // cd24
final bool? commandBuildBundleIsModule; // cd25
final String? commandResult; // cd26
final String? hotEventTargetPlatform; // cd27
final String? hotEventSdkName; // cd28
final bool? hotEventEmulator; // cd29
final bool? hotEventFullRestart; // cd30
final bool? commandHasTerminal; // cd31
final String? enabledFlutterFeatures; // cd32
final String? localTime; // cd33
final String? commandBuildAarTargetPlatform; // cd34
final String? commandBuildAarProjectType; // cd35
final String? buildEventCommand; // cd36
final String? buildEventSettings; // cd37
final String? commandBuildApkTargetPlatform; // cd38
final String? commandBuildApkBuildMode; // cd39
final bool? commandBuildApkSplitPerAbi; // cd40
final String? commandBuildAppBundleTargetPlatform; // cd41
final String? commandBuildAppBundleBuildMode; // cd42
final String? buildEventError; // cd43
final int? commandResultEventMaxRss; // cd44
final String? commandRunAndroidEmbeddingVersion; // cd45
final String? commandPackagesAndroidEmbeddingVersion; // cd46
final bool? nullSafety; // cd47
final bool? fastReassemble; // cd48
final int? nullSafeMigratedLibraries; // cd49
final int? nullSafeTotalLibraries; // cd50
/// Convert to a map that will be used to upload to the analytics backend.
Map<String, String> toMap() => <String, String>{
if (sessionHostOsDetails != null) cdKey(CustomDimensionsEnum.sessionHostOsDetails): sessionHostOsDetails.toString(),
if (sessionChannelName != null) cdKey(CustomDimensionsEnum.sessionChannelName): sessionChannelName.toString(),
if (commandRunIsEmulator != null) cdKey(CustomDimensionsEnum.commandRunIsEmulator): commandRunIsEmulator.toString(),
if (commandRunTargetName != null) cdKey(CustomDimensionsEnum.commandRunTargetName): commandRunTargetName.toString(),
if (hotEventReason != null) cdKey(CustomDimensionsEnum.hotEventReason): hotEventReason.toString(),
if (hotEventFinalLibraryCount != null) cdKey(CustomDimensionsEnum.hotEventFinalLibraryCount): hotEventFinalLibraryCount.toString(),
if (hotEventSyncedLibraryCount != null) cdKey(CustomDimensionsEnum.hotEventSyncedLibraryCount): hotEventSyncedLibraryCount.toString(),
if (hotEventSyncedClassesCount != null) cdKey(CustomDimensionsEnum.hotEventSyncedClassesCount): hotEventSyncedClassesCount.toString(),
if (hotEventSyncedProceduresCount != null) cdKey(CustomDimensionsEnum.hotEventSyncedProceduresCount): hotEventSyncedProceduresCount.toString(),
if (hotEventSyncedBytes != null) cdKey(CustomDimensionsEnum.hotEventSyncedBytes): hotEventSyncedBytes.toString(),
if (hotEventInvalidatedSourcesCount != null) cdKey(CustomDimensionsEnum.hotEventInvalidatedSourcesCount): hotEventInvalidatedSourcesCount.toString(),
if (hotEventTransferTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventTransferTimeInMs): hotEventTransferTimeInMs.toString(),
if (hotEventOverallTimeInMs != null) cdKey(CustomDimensionsEnum.hotEventOverallTimeInMs): hotEventOverallTimeInMs.toString(),
if (commandRunProjectType != null) cdKey(CustomDimensionsEnum.commandRunProjectType): commandRunProjectType.toString(),
if (commandRunProjectHostLanguage != null) cdKey(CustomDimensionsEnum.commandRunProjectHostLanguage): commandRunProjectHostLanguage.toString(),
if (commandCreateAndroidLanguage != null) cdKey(CustomDimensionsEnum.commandCreateAndroidLanguage): commandCreateAndroidLanguage.toString(),
if (commandCreateIosLanguage != null) cdKey(CustomDimensionsEnum.commandCreateIosLanguage): commandCreateIosLanguage.toString(),
if (commandRunProjectModule != null) cdKey(CustomDimensionsEnum.commandRunProjectModule): commandRunProjectModule.toString(),
if (commandCreateProjectType != null) cdKey(CustomDimensionsEnum.commandCreateProjectType): commandCreateProjectType.toString(),
if (commandPackagesNumberPlugins != null) cdKey(CustomDimensionsEnum.commandPackagesNumberPlugins): commandPackagesNumberPlugins.toString(),
if (commandPackagesProjectModule != null) cdKey(CustomDimensionsEnum.commandPackagesProjectModule): commandPackagesProjectModule.toString(),
if (commandRunTargetOsVersion != null) cdKey(CustomDimensionsEnum.commandRunTargetOsVersion): commandRunTargetOsVersion.toString(),
if (commandRunModeName != null) cdKey(CustomDimensionsEnum.commandRunModeName): commandRunModeName.toString(),
if (commandBuildBundleTargetPlatform != null) cdKey(CustomDimensionsEnum.commandBuildBundleTargetPlatform): commandBuildBundleTargetPlatform.toString(),
if (commandBuildBundleIsModule != null) cdKey(CustomDimensionsEnum.commandBuildBundleIsModule): commandBuildBundleIsModule.toString(),
if (commandResult != null) cdKey(CustomDimensionsEnum.commandResult): commandResult.toString(),
if (hotEventTargetPlatform != null) cdKey(CustomDimensionsEnum.hotEventTargetPlatform): hotEventTargetPlatform.toString(),
if (hotEventSdkName != null) cdKey(CustomDimensionsEnum.hotEventSdkName): hotEventSdkName.toString(),
if (hotEventEmulator != null) cdKey(CustomDimensionsEnum.hotEventEmulator): hotEventEmulator.toString(),
if (hotEventFullRestart != null) cdKey(CustomDimensionsEnum.hotEventFullRestart): hotEventFullRestart.toString(),
if (commandHasTerminal != null) cdKey(CustomDimensionsEnum.commandHasTerminal): commandHasTerminal.toString(),
if (enabledFlutterFeatures != null) cdKey(CustomDimensionsEnum.enabledFlutterFeatures): enabledFlutterFeatures.toString(),
if (localTime != null) cdKey(CustomDimensionsEnum.localTime): localTime.toString(),
if (commandBuildAarTargetPlatform != null) cdKey(CustomDimensionsEnum.commandBuildAarTargetPlatform): commandBuildAarTargetPlatform.toString(),
if (commandBuildAarProjectType != null) cdKey(CustomDimensionsEnum.commandBuildAarProjectType): commandBuildAarProjectType.toString(),
if (buildEventCommand != null) cdKey(CustomDimensionsEnum.buildEventCommand): buildEventCommand.toString(),
if (buildEventSettings != null) cdKey(CustomDimensionsEnum.buildEventSettings): buildEventSettings.toString(),
if (commandBuildApkTargetPlatform != null) cdKey(CustomDimensionsEnum.commandBuildApkTargetPlatform): commandBuildApkTargetPlatform.toString(),
if (commandBuildApkBuildMode != null) cdKey(CustomDimensionsEnum.commandBuildApkBuildMode): commandBuildApkBuildMode.toString(),
if (commandBuildApkSplitPerAbi != null) cdKey(CustomDimensionsEnum.commandBuildApkSplitPerAbi): commandBuildApkSplitPerAbi.toString(),
if (commandBuildAppBundleTargetPlatform != null) cdKey(CustomDimensionsEnum.commandBuildAppBundleTargetPlatform): commandBuildAppBundleTargetPlatform.toString(),
if (commandBuildAppBundleBuildMode != null) cdKey(CustomDimensionsEnum.commandBuildAppBundleBuildMode): commandBuildAppBundleBuildMode.toString(),
if (buildEventError != null) cdKey(CustomDimensionsEnum.buildEventError): buildEventError.toString(),
if (commandResultEventMaxRss != null) cdKey(CustomDimensionsEnum.commandResultEventMaxRss): commandResultEventMaxRss.toString(),
if (commandRunAndroidEmbeddingVersion != null) cdKey(CustomDimensionsEnum.commandRunAndroidEmbeddingVersion): commandRunAndroidEmbeddingVersion.toString(),
if (commandPackagesAndroidEmbeddingVersion != null) cdKey(CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion): commandPackagesAndroidEmbeddingVersion.toString(),
if (nullSafety != null) cdKey(CustomDimensionsEnum.nullSafety): nullSafety.toString(),
if (fastReassemble != null) cdKey(CustomDimensionsEnum.fastReassemble): fastReassemble.toString(),
if (nullSafeMigratedLibraries != null) cdKey(CustomDimensionsEnum.nullSafeMigratedLibraries): nullSafeMigratedLibraries.toString(),
if (nullSafeTotalLibraries != null) cdKey(CustomDimensionsEnum.nullSafeTotalLibraries): nullSafeTotalLibraries.toString(),
};
/// Merge the values of two [CustomDimensions] into one. If a value is defined
/// in both instances, the value in [other] will override the value in this.
CustomDimensions merge(CustomDimensions? other) {
if (other == null) {
return this;
}
return CustomDimensions(
sessionHostOsDetails: other.sessionHostOsDetails ?? sessionHostOsDetails,
sessionChannelName: other.sessionChannelName ?? sessionChannelName,
commandRunIsEmulator: other.commandRunIsEmulator ?? commandRunIsEmulator,
commandRunTargetName: other.commandRunTargetName ?? commandRunTargetName,
hotEventReason: other.hotEventReason ?? hotEventReason,
hotEventFinalLibraryCount: other.hotEventFinalLibraryCount ?? hotEventFinalLibraryCount,
hotEventSyncedLibraryCount: other.hotEventSyncedLibraryCount ?? hotEventSyncedLibraryCount,
hotEventSyncedClassesCount: other.hotEventSyncedClassesCount ?? hotEventSyncedClassesCount,
hotEventSyncedProceduresCount: other.hotEventSyncedProceduresCount ?? hotEventSyncedProceduresCount,
hotEventSyncedBytes: other.hotEventSyncedBytes ?? hotEventSyncedBytes,
hotEventInvalidatedSourcesCount: other.hotEventInvalidatedSourcesCount ?? hotEventInvalidatedSourcesCount,
hotEventTransferTimeInMs: other.hotEventTransferTimeInMs ?? hotEventTransferTimeInMs,
hotEventOverallTimeInMs: other.hotEventOverallTimeInMs ?? hotEventOverallTimeInMs,
commandRunProjectType: other.commandRunProjectType ?? commandRunProjectType,
commandRunProjectHostLanguage: other.commandRunProjectHostLanguage ?? commandRunProjectHostLanguage,
commandCreateAndroidLanguage: other.commandCreateAndroidLanguage ?? commandCreateAndroidLanguage,
commandCreateIosLanguage: other.commandCreateIosLanguage ?? commandCreateIosLanguage,
commandRunProjectModule: other.commandRunProjectModule ?? commandRunProjectModule,
commandCreateProjectType: other.commandCreateProjectType ?? commandCreateProjectType,
commandPackagesNumberPlugins: other.commandPackagesNumberPlugins ?? commandPackagesNumberPlugins,
commandPackagesProjectModule: other.commandPackagesProjectModule ?? commandPackagesProjectModule,
commandRunTargetOsVersion: other.commandRunTargetOsVersion ?? commandRunTargetOsVersion,
commandRunModeName: other.commandRunModeName ?? commandRunModeName,
commandBuildBundleTargetPlatform: other.commandBuildBundleTargetPlatform ?? commandBuildBundleTargetPlatform,
commandBuildBundleIsModule: other.commandBuildBundleIsModule ?? commandBuildBundleIsModule,
commandResult: other.commandResult ?? commandResult,
hotEventTargetPlatform: other.hotEventTargetPlatform ?? hotEventTargetPlatform,
hotEventSdkName: other.hotEventSdkName ?? hotEventSdkName,
hotEventEmulator: other.hotEventEmulator ?? hotEventEmulator,
hotEventFullRestart: other.hotEventFullRestart ?? hotEventFullRestart,
commandHasTerminal: other.commandHasTerminal ?? commandHasTerminal,
enabledFlutterFeatures: other.enabledFlutterFeatures ?? enabledFlutterFeatures,
localTime: other.localTime ?? localTime,
commandBuildAarTargetPlatform: other.commandBuildAarTargetPlatform ?? commandBuildAarTargetPlatform,
commandBuildAarProjectType: other.commandBuildAarProjectType ?? commandBuildAarProjectType,
buildEventCommand: other.buildEventCommand ?? buildEventCommand,
buildEventSettings: other.buildEventSettings ?? buildEventSettings,
commandBuildApkTargetPlatform: other.commandBuildApkTargetPlatform ?? commandBuildApkTargetPlatform,
commandBuildApkBuildMode: other.commandBuildApkBuildMode ?? commandBuildApkBuildMode,
commandBuildApkSplitPerAbi: other.commandBuildApkSplitPerAbi ?? commandBuildApkSplitPerAbi,
commandBuildAppBundleTargetPlatform: other.commandBuildAppBundleTargetPlatform ?? commandBuildAppBundleTargetPlatform,
commandBuildAppBundleBuildMode: other.commandBuildAppBundleBuildMode ?? commandBuildAppBundleBuildMode,
buildEventError: other.buildEventError ?? buildEventError,
commandResultEventMaxRss: other.commandResultEventMaxRss ?? commandResultEventMaxRss,
commandRunAndroidEmbeddingVersion: other.commandRunAndroidEmbeddingVersion ?? commandRunAndroidEmbeddingVersion,
commandPackagesAndroidEmbeddingVersion: other.commandPackagesAndroidEmbeddingVersion ?? commandPackagesAndroidEmbeddingVersion,
nullSafety: other.nullSafety ?? nullSafety,
fastReassemble: other.fastReassemble ?? fastReassemble,
nullSafeMigratedLibraries: other.nullSafeMigratedLibraries ?? nullSafeMigratedLibraries,
nullSafeTotalLibraries: other.nullSafeTotalLibraries ?? nullSafeTotalLibraries,
);
}
static CustomDimensions fromMap(Map<String, String> map) => CustomDimensions(
sessionHostOsDetails: _extractString(map, CustomDimensionsEnum.sessionHostOsDetails),
sessionChannelName: _extractString(map, CustomDimensionsEnum.sessionChannelName),
commandRunIsEmulator: _extractBool(map, CustomDimensionsEnum.commandRunIsEmulator),
commandRunTargetName: _extractString(map, CustomDimensionsEnum.commandRunTargetName),
hotEventReason: _extractString(map, CustomDimensionsEnum.hotEventReason),
hotEventFinalLibraryCount: _extractInt(map, CustomDimensionsEnum.hotEventFinalLibraryCount),
hotEventSyncedLibraryCount: _extractInt(map, CustomDimensionsEnum.hotEventSyncedLibraryCount),
hotEventSyncedClassesCount: _extractInt(map, CustomDimensionsEnum.hotEventSyncedClassesCount),
hotEventSyncedProceduresCount: _extractInt(map, CustomDimensionsEnum.hotEventSyncedProceduresCount),
hotEventSyncedBytes: _extractInt(map, CustomDimensionsEnum.hotEventSyncedBytes),
hotEventInvalidatedSourcesCount: _extractInt(map, CustomDimensionsEnum.hotEventInvalidatedSourcesCount),
hotEventTransferTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventTransferTimeInMs),
hotEventOverallTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventOverallTimeInMs),
commandRunProjectType: _extractString(map, CustomDimensionsEnum.commandRunProjectType),
commandRunProjectHostLanguage: _extractString(map, CustomDimensionsEnum.commandRunProjectHostLanguage),
commandCreateAndroidLanguage: _extractString(map, CustomDimensionsEnum.commandCreateAndroidLanguage),
commandCreateIosLanguage: _extractString(map, CustomDimensionsEnum.commandCreateIosLanguage),
commandRunProjectModule: _extractBool(map, CustomDimensionsEnum.commandRunProjectModule),
commandCreateProjectType: _extractString(map, CustomDimensionsEnum.commandCreateProjectType),
commandPackagesNumberPlugins: _extractInt(map, CustomDimensionsEnum.commandPackagesNumberPlugins),
commandPackagesProjectModule: _extractBool(map, CustomDimensionsEnum.commandPackagesProjectModule),
commandRunTargetOsVersion: _extractString(map, CustomDimensionsEnum.commandRunTargetOsVersion),
commandRunModeName: _extractString(map, CustomDimensionsEnum.commandRunModeName),
commandBuildBundleTargetPlatform: _extractString(map, CustomDimensionsEnum.commandBuildBundleTargetPlatform),
commandBuildBundleIsModule: _extractBool(map, CustomDimensionsEnum.commandBuildBundleIsModule),
commandResult: _extractString(map, CustomDimensionsEnum.commandResult),
hotEventTargetPlatform: _extractString(map, CustomDimensionsEnum.hotEventTargetPlatform),
hotEventSdkName: _extractString(map, CustomDimensionsEnum.hotEventSdkName),
hotEventEmulator: _extractBool(map, CustomDimensionsEnum.hotEventEmulator),
hotEventFullRestart: _extractBool(map, CustomDimensionsEnum.hotEventFullRestart),
commandHasTerminal: _extractBool(map, CustomDimensionsEnum.commandHasTerminal),
enabledFlutterFeatures: _extractString(map, CustomDimensionsEnum.enabledFlutterFeatures),
localTime: _extractString(map, CustomDimensionsEnum.localTime),
commandBuildAarTargetPlatform: _extractString(map, CustomDimensionsEnum.commandBuildAarTargetPlatform),
commandBuildAarProjectType: _extractString(map, CustomDimensionsEnum.commandBuildAarProjectType),
buildEventCommand: _extractString(map, CustomDimensionsEnum.buildEventCommand),
buildEventSettings: _extractString(map, CustomDimensionsEnum.buildEventSettings),
commandBuildApkTargetPlatform: _extractString(map, CustomDimensionsEnum.commandBuildApkTargetPlatform),
commandBuildApkBuildMode: _extractString(map, CustomDimensionsEnum.commandBuildApkBuildMode),
commandBuildApkSplitPerAbi: _extractBool(map, CustomDimensionsEnum.commandBuildApkSplitPerAbi),
commandBuildAppBundleTargetPlatform: _extractString(map, CustomDimensionsEnum.commandBuildAppBundleTargetPlatform),
commandBuildAppBundleBuildMode: _extractString(map, CustomDimensionsEnum.commandBuildAppBundleBuildMode),
buildEventError: _extractString(map, CustomDimensionsEnum.buildEventError),
commandResultEventMaxRss: _extractInt(map, CustomDimensionsEnum.commandResultEventMaxRss),
commandRunAndroidEmbeddingVersion: _extractString(map, CustomDimensionsEnum.commandRunAndroidEmbeddingVersion),
commandPackagesAndroidEmbeddingVersion: _extractString(map, CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion),
nullSafety: _extractBool(map, CustomDimensionsEnum.nullSafety),
fastReassemble: _extractBool(map, CustomDimensionsEnum.fastReassemble),
nullSafeMigratedLibraries: _extractInt(map, CustomDimensionsEnum.nullSafeMigratedLibraries),
nullSafeTotalLibraries: _extractInt(map, CustomDimensionsEnum.nullSafeTotalLibraries),
);
static bool? _extractBool(Map<String, String> map, CustomDimensionsEnum field) =>
map.containsKey(cdKey(field))? map[cdKey(field)] == 'true' : null;
static String? _extractString(Map<String, String> map, CustomDimensionsEnum field) =>
map.containsKey(cdKey(field))? map[cdKey(field)] : null;
static int? _extractInt(Map<String, String> map, CustomDimensionsEnum field) =>
map.containsKey(cdKey(field))? int.parse(map[cdKey(field)]!) : null;
@override
String toString() => toMap().toString();
@override
bool operator ==(Object other) {
return other is CustomDimensions &&
_mapsEqual(other.toMap(), toMap());
}
@override
int get hashCode =>
toMap()
.values
.where((String element) => element != null)
.fold(Object().hashCode,
(int value, String element) => value ^ element.hashCode);
}
/// List of all fields used in CustomDimensions.
///
/// The index of this enum is used to calculate the key of the fields. Always
/// append to this list when adding new fields, and do not remove or reorder
/// any elements.
enum CustomDimensionsEnum {
sessionHostOsDetails, // cd1
sessionChannelName, // cd2
commandRunIsEmulator, // cd3
commandRunTargetName, // cd4
hotEventReason, // cd5
hotEventFinalLibraryCount, // cd6
hotEventSyncedLibraryCount, // cd7
hotEventSyncedClassesCount, // cd8
hotEventSyncedProceduresCount, // cd9
hotEventSyncedBytes, // cd10
hotEventInvalidatedSourcesCount, // cd11
hotEventTransferTimeInMs, // cd12
hotEventOverallTimeInMs, // cd13
commandRunProjectType, // cd14
commandRunProjectHostLanguage, // cd15
commandCreateAndroidLanguage, // cd16
commandCreateIosLanguage, // cd17
commandRunProjectModule, // cd18
commandCreateProjectType, // cd19
commandPackagesNumberPlugins, // cd20
commandPackagesProjectModule, // cd21
commandRunTargetOsVersion, // cd22
commandRunModeName, // cd23
commandBuildBundleTargetPlatform, // cd24
commandBuildBundleIsModule, // cd25
commandResult, // cd26
hotEventTargetPlatform, // cd27
hotEventSdkName, // cd28
hotEventEmulator, // cd29
hotEventFullRestart, // cd30
commandHasTerminal, // cd31
enabledFlutterFeatures, // cd32
localTime, // cd33
commandBuildAarTargetPlatform, // cd34
commandBuildAarProjectType, // cd35
buildEventCommand, // cd36
buildEventSettings, // cd37
commandBuildApkTargetPlatform, // cd38
commandBuildApkBuildMode, // cd39
commandBuildApkSplitPerAbi, // cd40
commandBuildAppBundleTargetPlatform, // cd41
commandBuildAppBundleBuildMode, // cd42
buildEventError, // cd43
commandResultEventMaxRss, // cd44
commandRunAndroidEmbeddingVersion, // cd45
commandPackagesAndroidEmbeddingVersion, // cd46
nullSafety, // cd47
fastReassemble, // cd48
nullSafeMigratedLibraries, // cd49
nullSafeTotalLibraries, // cd50
}
String cdKey(CustomDimensionsEnum cd) => 'cd${cd.index + 1}';
...@@ -21,7 +21,7 @@ class DisabledUsage implements Usage { ...@@ -21,7 +21,7 @@ class DisabledUsage implements Usage {
String get clientId => ''; String get clientId => '';
@override @override
void sendCommand(String command, { Map<String, String>? parameters }) { } void sendCommand(String command, { CustomDimensions? parameters }) { }
@override @override
void sendEvent( void sendEvent(
...@@ -29,7 +29,7 @@ class DisabledUsage implements Usage { ...@@ -29,7 +29,7 @@ class DisabledUsage implements Usage {
String parameter, { String parameter, {
String? label, String? label,
int? value, int? value,
Map<String, String>? parameters, CustomDimensions? parameters,
}) { } }) { }
@override @override
......
...@@ -68,32 +68,22 @@ class HotEvent extends UsageEvent { ...@@ -68,32 +68,22 @@ class HotEvent extends UsageEvent {
@override @override
void send() { void send() {
final Map<String, String> parameters = _useCdKeys(<CustomDimensions, String>{ final CustomDimensions parameters = CustomDimensions(
CustomDimensions.hotEventTargetPlatform: targetPlatform, hotEventTargetPlatform: targetPlatform,
CustomDimensions.hotEventSdkName: sdkName, hotEventSdkName: sdkName,
CustomDimensions.hotEventEmulator: emulator.toString(), hotEventEmulator: emulator,
CustomDimensions.hotEventFullRestart: fullRestart.toString(), hotEventFullRestart: fullRestart,
if (reason != null) hotEventReason: reason,
CustomDimensions.hotEventReason: reason!, hotEventFinalLibraryCount: finalLibraryCount,
if (finalLibraryCount != null) hotEventSyncedLibraryCount: syncedLibraryCount,
CustomDimensions.hotEventFinalLibraryCount: finalLibraryCount.toString(), hotEventSyncedClassesCount: syncedClassesCount,
if (syncedLibraryCount != null) hotEventSyncedProceduresCount: syncedProceduresCount,
CustomDimensions.hotEventSyncedLibraryCount: syncedLibraryCount.toString(), hotEventSyncedBytes: syncedBytes,
if (syncedClassesCount != null) hotEventInvalidatedSourcesCount: invalidatedSourcesCount,
CustomDimensions.hotEventSyncedClassesCount: syncedClassesCount.toString(), hotEventTransferTimeInMs: transferTimeInMs,
if (syncedProceduresCount != null) hotEventOverallTimeInMs: overallTimeInMs,
CustomDimensions.hotEventSyncedProceduresCount: syncedProceduresCount.toString(), fastReassemble: fastReassemble,
if (syncedBytes != null) );
CustomDimensions.hotEventSyncedBytes: syncedBytes.toString(),
if (invalidatedSourcesCount != null)
CustomDimensions.hotEventInvalidatedSourcesCount: invalidatedSourcesCount.toString(),
if (transferTimeInMs != null)
CustomDimensions.hotEventTransferTimeInMs: transferTimeInMs.toString(),
if (overallTimeInMs != null)
CustomDimensions.hotEventOverallTimeInMs: overallTimeInMs.toString(),
if (fastReassemble != null)
CustomDimensions.fastReassemble: fastReassemble.toString(),
});
flutterUsage.sendEvent(category, parameter, parameters: parameters); flutterUsage.sendEvent(category, parameter, parameters: parameters);
} }
} }
...@@ -169,14 +159,11 @@ class BuildEvent extends UsageEvent { ...@@ -169,14 +159,11 @@ class BuildEvent extends UsageEvent {
@override @override
void send() { void send() {
final Map<String, String> parameters = _useCdKeys(<CustomDimensions, String>{ final CustomDimensions parameters = CustomDimensions(
if (_command != null) buildEventCommand: _command,
CustomDimensions.buildEventCommand: _command!, buildEventSettings: _settings,
if (_settings != null) buildEventError: _eventError,
CustomDimensions.buildEventSettings: _settings!, );
if (_eventError != null)
CustomDimensions.buildEventError: _eventError!,
});
flutterUsage.sendEvent( flutterUsage.sendEvent(
category, category,
parameter, parameter,
...@@ -290,10 +277,10 @@ class NullSafetyAnalysisEvent implements UsageEvent { ...@@ -290,10 +277,10 @@ class NullSafetyAnalysisEvent implements UsageEvent {
} }
} }
flutterUsage.sendEvent(kNullSafetyCategory, 'runtime-mode', label: nullSafetyMode.toString()); flutterUsage.sendEvent(kNullSafetyCategory, 'runtime-mode', label: nullSafetyMode.toString());
flutterUsage.sendEvent(kNullSafetyCategory, 'stats', parameters: <String, String>{ flutterUsage.sendEvent(kNullSafetyCategory, 'stats', parameters: CustomDimensions(
cdKey(CustomDimensions.nullSafeMigratedLibraries): migrated.toString(), nullSafeMigratedLibraries: migrated,
cdKey(CustomDimensions.nullSafeTotalLibraries): packageConfig.packages.length.toString(), nullSafeTotalLibraries: packageConfig.packages.length,
}); ));
if (languageVersion != null) { if (languageVersion != null) {
final String formattedVersion = '${languageVersion.major}.${languageVersion.minor}'; final String formattedVersion = '${languageVersion.major}.${languageVersion.minor}';
flutterUsage.sendEvent(kNullSafetyCategory, 'language-version', label: formattedVersion); flutterUsage.sendEvent(kNullSafetyCategory, 'language-version', label: formattedVersion);
......
...@@ -25,3 +25,4 @@ import 'first_run.dart'; ...@@ -25,3 +25,4 @@ import 'first_run.dart';
part 'disabled_usage.dart'; part 'disabled_usage.dart';
part 'events.dart'; part 'events.dart';
part 'usage.dart'; part 'usage.dart';
part 'custom_dimensions.dart';
...@@ -6,70 +6,6 @@ part of reporting; ...@@ -6,70 +6,6 @@ part of reporting;
const String _kFlutterUA = 'UA-67589403-6'; const String _kFlutterUA = 'UA-67589403-6';
/// The collection of custom dimensions understood by the analytics backend.
/// When adding to this list, first ensure that the custom dimension is
/// defined in the backend, or will be defined shortly after the relevant PR
/// lands.
enum CustomDimensions {
sessionHostOsDetails, // cd1
sessionChannelName, // cd2
commandRunIsEmulator, // cd3
commandRunTargetName, // cd4
hotEventReason, // cd5
hotEventFinalLibraryCount, // cd6
hotEventSyncedLibraryCount, // cd7
hotEventSyncedClassesCount, // cd8
hotEventSyncedProceduresCount, // cd9
hotEventSyncedBytes, // cd10
hotEventInvalidatedSourcesCount, // cd11
hotEventTransferTimeInMs, // cd12
hotEventOverallTimeInMs, // cd13
commandRunProjectType, // cd14
commandRunProjectHostLanguage, // cd15
commandCreateAndroidLanguage, // cd16
commandCreateIosLanguage, // cd17
commandRunProjectModule, // cd18
commandCreateProjectType, // cd19
commandPackagesNumberPlugins, // cd20
commandPackagesProjectModule, // cd21
commandRunTargetOsVersion, // cd22
commandRunModeName, // cd23
commandBuildBundleTargetPlatform, // cd24
commandBuildBundleIsModule, // cd25
commandResult, // cd26
hotEventTargetPlatform, // cd27
hotEventSdkName, // cd28
hotEventEmulator, // cd29
hotEventFullRestart, // cd30
commandHasTerminal, // cd31
enabledFlutterFeatures, // cd32
localTime, // cd33
commandBuildAarTargetPlatform, // cd34
commandBuildAarProjectType, // cd35
buildEventCommand, // cd36
buildEventSettings, // cd37
commandBuildApkTargetPlatform, // cd38
commandBuildApkBuildMode, // cd39
commandBuildApkSplitPerAbi, // cd40
commandBuildAppBundleTargetPlatform, // cd41
commandBuildAppBundleBuildMode, // cd42
buildEventError, // cd43
commandResultEventMaxRss, // cd44
commandRunAndroidEmbeddingVersion, // cd45
commandPackagesAndroidEmbeddingVersion, // cd46
nullSafety, // cd47
fastReassemble, // cd48
nullSafeMigratedLibraries, // cd49
nullSafeTotalLibraries, // cd 50
}
String cdKey(CustomDimensions cd) => 'cd${cd.index + 1}';
Map<String, String> _useCdKeys(Map<CustomDimensions, Object> parameters) {
return parameters.map((CustomDimensions k, Object v) =>
MapEntry<String, String>(cdKey(k), v.toString()));
}
abstract class Usage { abstract class Usage {
/// Create a new Usage instance; [versionOverride], [configDirOverride], and /// Create a new Usage instance; [versionOverride], [configDirOverride], and
/// [logFile] are used for testing. /// [logFile] are used for testing.
...@@ -94,8 +30,8 @@ abstract class Usage { ...@@ -94,8 +30,8 @@ abstract class Usage {
/// Uses the global [Usage] instance to send a 'command' to analytics. /// Uses the global [Usage] instance to send a 'command' to analytics.
static void command(String command, { static void command(String command, {
Map<CustomDimensions, Object>? parameters, CustomDimensions? parameters,
}) => globals.flutterUsage.sendCommand(command, parameters: parameters == null ? null : _useCdKeys(parameters)); }) => globals.flutterUsage.sendCommand(command, parameters: parameters);
/// Whether analytics reporting should be suppressed. /// Whether analytics reporting should be suppressed.
bool get suppressAnalytics; bool get suppressAnalytics;
...@@ -119,7 +55,7 @@ abstract class Usage { ...@@ -119,7 +55,7 @@ abstract class Usage {
/// keys are well-defined in [CustomDimensions] above. /// keys are well-defined in [CustomDimensions] above.
void sendCommand( void sendCommand(
String command, { String command, {
Map<String, String>? parameters, CustomDimensions? parameters,
}); });
/// Sends an 'event' to the underlying analytics implementation. /// Sends an 'event' to the underlying analytics implementation.
...@@ -133,7 +69,7 @@ abstract class Usage { ...@@ -133,7 +69,7 @@ abstract class Usage {
String parameter, { String parameter, {
String? label, String? label,
int? value, int? value,
Map<String, String>? parameters, CustomDimensions? parameters,
}); });
/// Sends timing information to the underlying analytics implementation. /// Sends timing information to the underlying analytics implementation.
...@@ -256,12 +192,12 @@ class _DefaultUsage implements Usage { ...@@ -256,12 +192,12 @@ class _DefaultUsage implements Usage {
if (!skipAnalyticsSessionSetup) { if (!skipAnalyticsSessionSetup) {
// Report a more detailed OS version string than package:usage does by default. // Report a more detailed OS version string than package:usage does by default.
analytics.setSessionValue( analytics.setSessionValue(
cdKey(CustomDimensions.sessionHostOsDetails), cdKey(CustomDimensionsEnum.sessionHostOsDetails),
globals.os.name, globals.os.name,
); );
// Send the branch name as the "channel". // Send the branch name as the "channel".
analytics.setSessionValue( analytics.setSessionValue(
cdKey(CustomDimensions.sessionChannelName), cdKey(CustomDimensionsEnum.sessionChannelName),
flutterVersion.getBranchName(redactUnknownBranches: true), flutterVersion.getBranchName(redactUnknownBranches: true),
); );
// For each flutter experimental feature, record a session value in a comma // For each flutter experimental feature, record a session value in a comma
...@@ -274,7 +210,7 @@ class _DefaultUsage implements Usage { ...@@ -274,7 +210,7 @@ class _DefaultUsage implements Usage {
.map((Feature feature) => feature.configSetting) .map((Feature feature) => feature.configSetting)
.join(','); .join(',');
analytics.setSessionValue( analytics.setSessionValue(
cdKey(CustomDimensions.enabledFlutterFeatures), cdKey(CustomDimensionsEnum.enabledFlutterFeatures),
enabledFeatures, enabledFeatures,
); );
...@@ -320,16 +256,17 @@ class _DefaultUsage implements Usage { ...@@ -320,16 +256,17 @@ class _DefaultUsage implements Usage {
String get clientId => _analytics.clientId; String get clientId => _analytics.clientId;
@override @override
void sendCommand(String command, { Map<String, String>? parameters }) { void sendCommand(String command, { CustomDimensions? parameters }) {
if (suppressAnalytics) { if (suppressAnalytics) {
return; return;
} }
final Map<String, String> paramsWithLocalTime = <String, String>{ _analytics.sendScreenView(
...?parameters, command,
cdKey(CustomDimensions.localTime): formatDateTime(_clock.now()), parameters: CustomDimensions(localTime: formatDateTime(_clock.now()))
}; .merge(parameters)
_analytics.sendScreenView(command, parameters: paramsWithLocalTime); .toMap(),
);
} }
@override @override
...@@ -338,23 +275,20 @@ class _DefaultUsage implements Usage { ...@@ -338,23 +275,20 @@ class _DefaultUsage implements Usage {
String parameter, { String parameter, {
String? label, String? label,
int? value, int? value,
Map<String, String>? parameters, CustomDimensions? parameters,
}) { }) {
if (suppressAnalytics) { if (suppressAnalytics) {
return; return;
} }
final Map<String, String> paramsWithLocalTime = <String, String>{
...?parameters,
cdKey(CustomDimensions.localTime): formatDateTime(_clock.now()),
};
_analytics.sendEvent( _analytics.sendEvent(
category, category,
parameter, parameter,
label: label, label: label,
value: value, value: value,
parameters: paramsWithLocalTime, parameters: CustomDimensions(localTime: formatDateTime(_clock.now()))
.merge(parameters)
.toMap(),
); );
} }
...@@ -516,12 +450,12 @@ class TestUsage implements Usage { ...@@ -516,12 +450,12 @@ class TestUsage implements Usage {
void printWelcome() { } void printWelcome() { }
@override @override
void sendCommand(String command, {Map<String, String>? parameters}) { void sendCommand(String command, {CustomDimensions? parameters}) {
commands.add(TestUsageCommand(command, parameters: parameters)); commands.add(TestUsageCommand(command, parameters: parameters));
} }
@override @override
void sendEvent(String category, String parameter, {String? label, int? value, Map<String, String>? parameters}) { void sendEvent(String category, String parameter, {String? label, int? value, CustomDimensions? parameters}) {
events.add(TestUsageEvent(category, parameter, label: label, value: value, parameters: parameters)); events.add(TestUsageEvent(category, parameter, label: label, value: value, parameters: parameters));
} }
...@@ -542,13 +476,13 @@ class TestUsageCommand { ...@@ -542,13 +476,13 @@ class TestUsageCommand {
const TestUsageCommand(this.command, {this.parameters}); const TestUsageCommand(this.command, {this.parameters});
final String command; final String command;
final Map<String, String>? parameters; final CustomDimensions? parameters;
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is TestUsageCommand && return other is TestUsageCommand &&
other.command == command && other.command == command &&
_mapsEqual(other.parameters, parameters); other.parameters == parameters;
} }
@override @override
...@@ -567,7 +501,7 @@ class TestUsageEvent { ...@@ -567,7 +501,7 @@ class TestUsageEvent {
final String parameter; final String parameter;
final String? label; final String? label;
final int? value; final int? value;
final Map<String, String>? parameters; final CustomDimensions? parameters;
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
...@@ -576,7 +510,7 @@ class TestUsageEvent { ...@@ -576,7 +510,7 @@ class TestUsageEvent {
other.parameter == parameter && other.parameter == parameter &&
other.label == label && other.label == label &&
other.value == value && other.value == value &&
_mapsEqual(other.parameters, parameters); other.parameters == parameters;
} }
@override @override
......
...@@ -1063,8 +1063,7 @@ abstract class FlutterCommand extends Command<void> { ...@@ -1063,8 +1063,7 @@ abstract class FlutterCommand extends Command<void> {
} }
/// Additional usage values to be sent with the usage ping. /// Additional usage values to be sent with the usage ping.
Future<Map<CustomDimensions, String>> get usageValues async => Future<CustomDimensions> get usageValues async => const CustomDimensions();
const <CustomDimensions, String>{};
/// Runs this command. /// Runs this command.
/// ///
...@@ -1231,12 +1230,9 @@ abstract class FlutterCommand extends Command<void> { ...@@ -1231,12 +1230,9 @@ abstract class FlutterCommand extends Command<void> {
setupApplicationPackages(); setupApplicationPackages();
if (commandPath != null) { if (commandPath != null) {
final Map<CustomDimensions, Object> additionalUsageValues = Usage.command(commandPath, parameters: CustomDimensions(
<CustomDimensions, Object>{ commandHasTerminal: globals.stdio.hasTerminal,
...?await usageValues, ).merge(await usageValues));
CustomDimensions.commandHasTerminal: globals.stdio.hasTerminal,
};
Usage.command(commandPath, parameters: additionalUsageValues);
} }
return runCommand(); return runCommand();
......
...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/convert.dart'; ...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/doctor_validator.dart'; import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals; import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/test_flutter_command_runner.dart'; import '../../src/test_flutter_command_runner.dart';
...@@ -72,16 +71,16 @@ void main() { ...@@ -72,16 +71,16 @@ void main() {
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--no-pub', '--template=module', 'testy']); await runner.run(<String>['create', '--no-pub', '--template=module', 'testy']);
expect(await command.usageValues, containsPair(CustomDimensions.commandCreateProjectType, 'module')); expect((await command.usageValues).commandCreateProjectType, 'module');
await runner.run(<String>['create', '--no-pub', '--template=app', 'testy']); await runner.run(<String>['create', '--no-pub', '--template=app', 'testy']);
expect(await command.usageValues, containsPair(CustomDimensions.commandCreateProjectType, 'app')); expect((await command.usageValues).commandCreateProjectType, 'app');
await runner.run(<String>['create', '--no-pub', '--template=package', 'testy']); await runner.run(<String>['create', '--no-pub', '--template=package', 'testy']);
expect(await command.usageValues, containsPair(CustomDimensions.commandCreateProjectType, 'package')); expect((await command.usageValues).commandCreateProjectType, 'package');
await runner.run(<String>['create', '--no-pub', '--template=plugin', 'testy']); await runner.run(<String>['create', '--no-pub', '--template=plugin', 'testy']);
expect(await command.usageValues, containsPair(CustomDimensions.commandCreateProjectType, 'plugin')); expect((await command.usageValues).commandCreateProjectType, 'plugin');
})); }));
testUsingContext('set iOS host language type as usage value', () => testbed.run(() async { testUsingContext('set iOS host language type as usage value', () => testbed.run(() async {
...@@ -90,8 +89,7 @@ void main() { ...@@ -90,8 +89,7 @@ void main() {
await runner.run(<String>[ await runner.run(<String>[
'create', '--no-pub', '--template=app', 'testy']); 'create', '--no-pub', '--template=app', 'testy']);
expect(await command.usageValues, expect((await command.usageValues).commandCreateIosLanguage, 'swift');
containsPair(CustomDimensions.commandCreateIosLanguage, 'swift'));
await runner.run(<String>[ await runner.run(<String>[
'create', 'create',
...@@ -100,8 +98,7 @@ void main() { ...@@ -100,8 +98,7 @@ void main() {
'--ios-language=objc', '--ios-language=objc',
'testy', 'testy',
]); ]);
expect(await command.usageValues, expect((await command.usageValues).commandCreateIosLanguage, 'objc');
containsPair(CustomDimensions.commandCreateIosLanguage, 'objc'));
})); }));
...@@ -110,8 +107,7 @@ void main() { ...@@ -110,8 +107,7 @@ void main() {
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--no-pub', '--template=app', 'testy']); await runner.run(<String>['create', '--no-pub', '--template=app', 'testy']);
expect(await command.usageValues, expect((await command.usageValues).commandCreateAndroidLanguage, 'kotlin');
containsPair(CustomDimensions.commandCreateAndroidLanguage, 'kotlin'));
await runner.run(<String>[ await runner.run(<String>[
'create', 'create',
...@@ -120,8 +116,7 @@ void main() { ...@@ -120,8 +116,7 @@ void main() {
'--android-language=java', '--android-language=java',
'testy', 'testy',
]); ]);
expect(await command.usageValues, expect((await command.usageValues).commandCreateAndroidLanguage, 'java');
containsPair(CustomDimensions.commandCreateAndroidLanguage, 'java'));
})); }));
}); });
} }
......
...@@ -41,11 +41,11 @@ void main() { ...@@ -41,11 +41,11 @@ void main() {
await commandRunner.run(<String>['get']); await commandRunner.run(<String>['get']);
expect(await command.usageValues, <CustomDimensions, Object>{ expect(await command.usageValues, const CustomDimensions(
CustomDimensions.commandPackagesNumberPlugins: '0', commandPackagesNumberPlugins: 0,
CustomDimensions.commandPackagesProjectModule: 'false', commandPackagesProjectModule: false,
CustomDimensions.commandPackagesAndroidEmbeddingVersion: 'v1' commandPackagesAndroidEmbeddingVersion: 'v1',
}); ));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => pub, Pub: () => pub,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -66,11 +66,11 @@ void main() { ...@@ -66,11 +66,11 @@ void main() {
await commandRunner.run(<String>['get']); await commandRunner.run(<String>['get']);
expect(await command.usageValues, <CustomDimensions, Object>{ expect(await command.usageValues, const CustomDimensions(
CustomDimensions.commandPackagesNumberPlugins: '0', commandPackagesNumberPlugins: 0,
CustomDimensions.commandPackagesProjectModule: 'false', commandPackagesProjectModule: false,
CustomDimensions.commandPackagesAndroidEmbeddingVersion: 'v1' commandPackagesAndroidEmbeddingVersion: 'v1',
}); ));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => pub, Pub: () => pub,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -86,11 +86,11 @@ void main() { ...@@ -86,11 +86,11 @@ void main() {
await commandRunner.run(<String>['get']); await commandRunner.run(<String>['get']);
expect(await command.usageValues, <CustomDimensions, Object>{ expect(await command.usageValues, const CustomDimensions(
CustomDimensions.commandPackagesNumberPlugins: '0', commandPackagesNumberPlugins: 0,
CustomDimensions.commandPackagesProjectModule: 'false', commandPackagesProjectModule: false,
CustomDimensions.commandPackagesAndroidEmbeddingVersion: 'v1' commandPackagesAndroidEmbeddingVersion: 'v1',
}); ));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => pub, Pub: () => pub,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
......
...@@ -368,10 +368,10 @@ void main() { ...@@ -368,10 +368,10 @@ void main() {
]), isNull); ]), isNull);
expect(usage.commands, contains( expect(usage.commands, contains(
const TestUsageCommand('run', parameters: <String, String>{ TestUsageCommand('run', parameters: CustomDimensions.fromMap(<String, String>{
'cd3': 'false', 'cd4': 'ios', 'cd22': 'iOS 13', 'cd3': 'false', 'cd4': 'ios', 'cd22': 'iOS 13',
'cd23': 'debug', 'cd18': 'false', 'cd15': 'swift', 'cd31': 'false', 'cd23': 'debug', 'cd18': 'false', 'cd15': 'swift', 'cd31': 'false',
} })
))); )));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Artifacts: () => artifacts, Artifacts: () => artifacts,
......
...@@ -55,8 +55,7 @@ void main() { ...@@ -55,8 +55,7 @@ void main() {
arguments: <String>['--no-pub', '--template=module']); arguments: <String>['--no-pub', '--template=module']);
final BuildAarCommand command = await runCommandIn(projectPath); final BuildAarCommand command = await runCommandIn(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildAarProjectType, 'module');
containsPair(CustomDimensions.commandBuildAarProjectType, 'module'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -67,8 +66,7 @@ void main() { ...@@ -67,8 +66,7 @@ void main() {
arguments: <String>['--no-pub', '--template=plugin', '--project-name=aar_test']); arguments: <String>['--no-pub', '--template=plugin', '--project-name=aar_test']);
final BuildAarCommand command = await runCommandIn(projectPath); final BuildAarCommand command = await runCommandIn(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildAarProjectType, 'plugin');
containsPair(CustomDimensions.commandBuildAarProjectType, 'plugin'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -80,8 +78,7 @@ void main() { ...@@ -80,8 +78,7 @@ void main() {
final BuildAarCommand command = await runCommandIn(projectPath, final BuildAarCommand command = await runCommandIn(projectPath,
arguments: <String>['--target-platform=android-arm']); arguments: <String>['--target-platform=android-arm']);
expect(await command.usageValues, expect((await command.usageValues).commandBuildAarTargetPlatform, 'android-arm');
containsPair(CustomDimensions.commandBuildAarTargetPlatform, 'android-arm'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
......
...@@ -43,8 +43,7 @@ void main() { ...@@ -43,8 +43,7 @@ void main() {
arguments: <String>['--no-pub', '--template=app']); arguments: <String>['--no-pub', '--template=app']);
final BuildApkCommand command = await runBuildApkCommand(projectPath); final BuildApkCommand command = await runBuildApkCommand(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildApkTargetPlatform, 'android-arm,android-arm64,android-x64');
containsPair(CustomDimensions.commandBuildApkTargetPlatform, 'android-arm,android-arm64,android-x64'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -56,12 +55,10 @@ void main() { ...@@ -56,12 +55,10 @@ void main() {
final BuildApkCommand commandWithFlag = await runBuildApkCommand(projectPath, final BuildApkCommand commandWithFlag = await runBuildApkCommand(projectPath,
arguments: <String>['--split-per-abi']); arguments: <String>['--split-per-abi']);
expect(await commandWithFlag.usageValues, expect((await commandWithFlag.usageValues).commandBuildApkSplitPerAbi, true);
containsPair(CustomDimensions.commandBuildApkSplitPerAbi, 'true'));
final BuildApkCommand commandWithoutFlag = await runBuildApkCommand(projectPath); final BuildApkCommand commandWithoutFlag = await runBuildApkCommand(projectPath);
expect(await commandWithoutFlag.usageValues, expect((await commandWithoutFlag.usageValues).commandBuildApkSplitPerAbi, false);
containsPair(CustomDimensions.commandBuildApkSplitPerAbi, 'false'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -72,23 +69,19 @@ void main() { ...@@ -72,23 +69,19 @@ void main() {
arguments: <String>['--no-pub', '--template=app']); arguments: <String>['--no-pub', '--template=app']);
final BuildApkCommand commandDefault = await runBuildApkCommand(projectPath); final BuildApkCommand commandDefault = await runBuildApkCommand(projectPath);
expect(await commandDefault.usageValues, expect((await commandDefault.usageValues).commandBuildApkBuildMode, 'release');
containsPair(CustomDimensions.commandBuildApkBuildMode, 'release'));
final BuildApkCommand commandInRelease = await runBuildApkCommand(projectPath, final BuildApkCommand commandInRelease = await runBuildApkCommand(projectPath,
arguments: <String>['--release']); arguments: <String>['--release']);
expect(await commandInRelease.usageValues, expect((await commandInRelease.usageValues).commandBuildApkBuildMode, 'release');
containsPair(CustomDimensions.commandBuildApkBuildMode, 'release'));
final BuildApkCommand commandInDebug = await runBuildApkCommand(projectPath, final BuildApkCommand commandInDebug = await runBuildApkCommand(projectPath,
arguments: <String>['--debug']); arguments: <String>['--debug']);
expect(await commandInDebug.usageValues, expect((await commandInDebug.usageValues).commandBuildApkBuildMode, 'debug');
containsPair(CustomDimensions.commandBuildApkBuildMode, 'debug'));
final BuildApkCommand commandInProfile = await runBuildApkCommand(projectPath, final BuildApkCommand commandInProfile = await runBuildApkCommand(projectPath,
arguments: <String>['--profile']); arguments: <String>['--profile']);
expect(await commandInProfile.usageValues, expect((await commandInProfile.usageValues).commandBuildApkBuildMode, 'profile');
containsPair(CustomDimensions.commandBuildApkBuildMode, 'profile'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -315,7 +308,7 @@ void main() { ...@@ -315,7 +308,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-r8-failure', label: 'gradle-r8-failure',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
...@@ -368,7 +361,7 @@ void main() { ...@@ -368,7 +361,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'app-not-using-android-x', label: 'app-not-using-android-x',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
...@@ -414,7 +407,7 @@ void main() { ...@@ -414,7 +407,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'app-using-android-x', label: 'app-using-android-x',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
......
...@@ -41,8 +41,7 @@ void main() { ...@@ -41,8 +41,7 @@ void main() {
arguments: <String>['--no-pub', '--template=app']); arguments: <String>['--no-pub', '--template=app']);
final BuildAppBundleCommand command = await runBuildAppBundleCommand(projectPath); final BuildAppBundleCommand command = await runBuildAppBundleCommand(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildAppBundleTargetPlatform, 'android-arm,android-arm64,android-x64');
containsPair(CustomDimensions.commandBuildAppBundleTargetPlatform, 'android-arm,android-arm64,android-x64'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -53,23 +52,19 @@ void main() { ...@@ -53,23 +52,19 @@ void main() {
arguments: <String>['--no-pub', '--template=app']); arguments: <String>['--no-pub', '--template=app']);
final BuildAppBundleCommand commandDefault = await runBuildAppBundleCommand(projectPath); final BuildAppBundleCommand commandDefault = await runBuildAppBundleCommand(projectPath);
expect(await commandDefault.usageValues, expect((await commandDefault.usageValues).commandBuildAppBundleBuildMode, 'release');
containsPair(CustomDimensions.commandBuildAppBundleBuildMode, 'release'));
final BuildAppBundleCommand commandInRelease = await runBuildAppBundleCommand(projectPath, final BuildAppBundleCommand commandInRelease = await runBuildAppBundleCommand(projectPath,
arguments: <String>['--release']); arguments: <String>['--release']);
expect(await commandInRelease.usageValues, expect((await commandInRelease.usageValues).commandBuildAppBundleBuildMode, 'release');
containsPair(CustomDimensions.commandBuildAppBundleBuildMode, 'release'));
final BuildAppBundleCommand commandInDebug = await runBuildAppBundleCommand(projectPath, final BuildAppBundleCommand commandInDebug = await runBuildAppBundleCommand(projectPath,
arguments: <String>['--debug']); arguments: <String>['--debug']);
expect(await commandInDebug.usageValues, expect((await commandInDebug.usageValues).commandBuildAppBundleBuildMode, 'debug');
containsPair(CustomDimensions.commandBuildAppBundleBuildMode, 'debug'));
final BuildAppBundleCommand commandInProfile = await runBuildAppBundleCommand(projectPath, final BuildAppBundleCommand commandInProfile = await runBuildAppBundleCommand(projectPath,
arguments: <String>['--profile']); arguments: <String>['--profile']);
expect(await commandInProfile.usageValues, expect((await commandInProfile.usageValues).commandBuildAppBundleBuildMode, 'profile');
containsPair(CustomDimensions.commandBuildAppBundleBuildMode, 'profile'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => FakeAndroidBuilder(), AndroidBuilder: () => FakeAndroidBuilder(),
...@@ -163,7 +158,7 @@ void main() { ...@@ -163,7 +158,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'app-not-using-android-x', label: 'app-not-using-android-x',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
}, },
...@@ -203,7 +198,7 @@ void main() { ...@@ -203,7 +198,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'app-using-android-x', label: 'app-using-android-x',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
}, },
......
...@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/commands/build_bundle.dart'; ...@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/commands/build_bundle.dart';
import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals; import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:test/fake.dart'; import 'package:test/fake.dart';
...@@ -58,8 +57,7 @@ void main() { ...@@ -58,8 +57,7 @@ void main() {
final BuildBundleCommand command = await runCommandIn(projectPath); final BuildBundleCommand command = await runCommandIn(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildBundleIsModule, true);
containsPair(CustomDimensions.commandBuildBundleIsModule, 'true'));
}); });
testUsingContext('bundle getUsage indicate that project is not a module', () async { testUsingContext('bundle getUsage indicate that project is not a module', () async {
...@@ -68,8 +66,7 @@ void main() { ...@@ -68,8 +66,7 @@ void main() {
final BuildBundleCommand command = await runCommandIn(projectPath); final BuildBundleCommand command = await runCommandIn(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildBundleIsModule, false);
containsPair(CustomDimensions.commandBuildBundleIsModule, 'false'));
}); });
testUsingContext('bundle getUsage indicate the target platform', () async { testUsingContext('bundle getUsage indicate the target platform', () async {
...@@ -78,8 +75,7 @@ void main() { ...@@ -78,8 +75,7 @@ void main() {
final BuildBundleCommand command = await runCommandIn(projectPath); final BuildBundleCommand command = await runCommandIn(projectPath);
expect(await command.usageValues, expect((await command.usageValues).commandBuildBundleTargetPlatform, 'android-arm');
containsPair(CustomDimensions.commandBuildBundleTargetPlatform, 'android-arm'));
}); });
testUsingContext('bundle fails to build for Windows if feature is disabled', () async { testUsingContext('bundle fails to build for Windows if feature is disabled', () async {
......
...@@ -18,7 +18,6 @@ import 'package:flutter_tools/src/cache.dart'; ...@@ -18,7 +18,6 @@ import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/packages.dart'; import 'package:flutter_tools/src/commands/packages.dart';
import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals; import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
...@@ -240,8 +239,7 @@ void main() { ...@@ -240,8 +239,7 @@ void main() {
final PackagesCommand command = await runCommandIn(projectPath, 'get'); final PackagesCommand command = await runCommandIn(projectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesNumberPlugins, 0);
containsPair(CustomDimensions.commandPackagesNumberPlugins, '0'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -263,8 +261,7 @@ void main() { ...@@ -263,8 +261,7 @@ void main() {
final PackagesCommand command = await runCommandIn(exampleProjectPath, 'get'); final PackagesCommand command = await runCommandIn(exampleProjectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesNumberPlugins, 1);
containsPair(CustomDimensions.commandPackagesNumberPlugins, '1'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -284,8 +281,7 @@ void main() { ...@@ -284,8 +281,7 @@ void main() {
final PackagesCommand command = await runCommandIn(projectPath, 'get'); final PackagesCommand command = await runCommandIn(projectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesProjectModule, false);
containsPair(CustomDimensions.commandPackagesProjectModule, 'false'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -305,8 +301,7 @@ void main() { ...@@ -305,8 +301,7 @@ void main() {
final PackagesCommand command = await runCommandIn(projectPath, 'get'); final PackagesCommand command = await runCommandIn(projectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesProjectModule, true);
containsPair(CustomDimensions.commandPackagesProjectModule, 'true'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -335,8 +330,7 @@ void main() { ...@@ -335,8 +330,7 @@ void main() {
final PackagesCommand command = await runCommandIn(projectPath, 'get'); final PackagesCommand command = await runCommandIn(projectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v1');
containsPair(CustomDimensions.commandPackagesAndroidEmbeddingVersion, 'v1'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
...@@ -356,8 +350,7 @@ void main() { ...@@ -356,8 +350,7 @@ void main() {
final PackagesCommand command = await runCommandIn(projectPath, 'get'); final PackagesCommand command = await runCommandIn(projectPath, 'get');
final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand; final PackagesGetCommand getCommand = command.subcommands['get'] as PackagesGetCommand;
expect(await getCommand.usageValues, expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v2');
containsPair(CustomDimensions.commandPackagesAndroidEmbeddingVersion, 'v2'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Pub: () => Pub( Pub: () => Pub(
fileSystem: globals.fs, fileSystem: globals.fs,
......
...@@ -111,7 +111,7 @@ void main() { ...@@ -111,7 +111,7 @@ void main() {
final Usage usage = Usage(runningOnBot: true); final Usage usage = Usage(runningOnBot: true);
usage.sendCommand('test'); usage.sendCommand('test');
final String featuresKey = cdKey(CustomDimensions.enabledFlutterFeatures); final String featuresKey = cdKey(CustomDimensionsEnum.enabledFlutterFeatures);
expect(globals.fs.file('test').readAsStringSync(), contains('$featuresKey: enable-web')); expect(globals.fs.file('test').readAsStringSync(), contains('$featuresKey: enable-web'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -131,7 +131,7 @@ void main() { ...@@ -131,7 +131,7 @@ void main() {
final Usage usage = Usage(runningOnBot: true); final Usage usage = Usage(runningOnBot: true);
usage.sendCommand('test'); usage.sendCommand('test');
final String featuresKey = cdKey(CustomDimensions.enabledFlutterFeatures); final String featuresKey = cdKey(CustomDimensionsEnum.enabledFlutterFeatures);
expect( expect(
globals.fs.file('test').readAsStringSync(), globals.fs.file('test').readAsStringSync(),
......
...@@ -122,7 +122,7 @@ void main() { ...@@ -122,7 +122,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-random-event-label-failure', label: 'gradle-random-event-label-failure',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
}); });
...@@ -224,7 +224,7 @@ void main() { ...@@ -224,7 +224,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-random-event-label-failure', label: 'gradle-random-event-label-failure',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
}); });
...@@ -311,7 +311,7 @@ void main() { ...@@ -311,7 +311,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-random-event-label-failure', label: 'gradle-random-event-label-failure',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
}); });
...@@ -467,7 +467,7 @@ void main() { ...@@ -467,7 +467,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-random-event-label-success', label: 'gradle-random-event-label-success',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
...@@ -675,7 +675,7 @@ void main() { ...@@ -675,7 +675,7 @@ void main() {
'build', 'build',
'gradle', 'gradle',
label: 'gradle-random-event-label-failure', label: 'gradle-random-event-label-failure',
parameters: <String, String>{}, parameters: CustomDimensions(),
), ),
)); ));
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
......
...@@ -355,13 +355,13 @@ Command: /home/android/gradlew assembleRelease ...@@ -355,13 +355,13 @@ Command: /home/android/gradlew assembleRelease
.handler(line: '', project: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory)); .handler(line: '', project: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory));
expect(testUsage.events, contains( expect(testUsage.events, contains(
const TestUsageEvent( TestUsageEvent(
'build', 'build',
'gradle', 'gradle',
label: 'gradle-android-x-failure', label: 'gradle-android-x-failure',
parameters: <String, String>{ parameters: CustomDimensions.fromMap(<String, String>{
'cd43': 'app-not-using-plugins', 'cd43': 'app-not-using-plugins',
}, }),
), ),
)); ));
...@@ -390,13 +390,13 @@ Command: /home/android/gradlew assembleRelease ...@@ -390,13 +390,13 @@ Command: /home/android/gradlew assembleRelease
); );
expect(testUsage.events, contains( expect(testUsage.events, contains(
const TestUsageEvent( TestUsageEvent(
'build', 'build',
'gradle', 'gradle',
label: 'gradle-android-x-failure', label: 'gradle-android-x-failure',
parameters: <String, String>{ parameters: CustomDimensions.fromMap(<String, String>{
'cd43': 'app-not-using-androidx', 'cd43': 'app-not-using-androidx',
}, }),
), ),
)); ));
...@@ -418,13 +418,13 @@ Command: /home/android/gradlew assembleRelease ...@@ -418,13 +418,13 @@ Command: /home/android/gradlew assembleRelease
); );
expect(testUsage.events, contains( expect(testUsage.events, contains(
const TestUsageEvent( TestUsageEvent(
'build', 'build',
'gradle', 'gradle',
label: 'gradle-android-x-failure', label: 'gradle-android-x-failure',
parameters: <String, String>{ parameters: CustomDimensions.fromMap(<String, String>{
'cd43': 'using-jetifier', 'cd43': 'using-jetifier',
}, }),
), ),
)); ));
...@@ -453,13 +453,13 @@ Command: /home/android/gradlew assembleRelease ...@@ -453,13 +453,13 @@ Command: /home/android/gradlew assembleRelease
); );
expect(testUsage.events, contains( expect(testUsage.events, contains(
const TestUsageEvent( TestUsageEvent(
'build', 'build',
'gradle', 'gradle',
label: 'gradle-android-x-failure', label: 'gradle-android-x-failure',
parameters: <String, String>{ parameters: CustomDimensions.fromMap(<String, String>{
'cd43': 'not-using-jetifier', 'cd43': 'not-using-jetifier',
}, }),
), ),
)); ));
expect(status, equals(GradleBuildStatus.retryWithAarPlugins)); expect(status, equals(GradleBuildStatus.retryWithAarPlugins));
......
...@@ -326,13 +326,13 @@ void main() { ...@@ -326,13 +326,13 @@ void main() {
) )
); );
expect(testUsage.events, contains( expect(testUsage.events, contains(
const TestUsageEvent( TestUsageEvent(
'build', 'build',
'gradle', 'gradle',
label: 'gradle-expected-file-not-found', label: 'gradle-expected-file-not-found',
parameters: <String, String> { parameters: CustomDimensions.fromMap(<String, String> {
'cd37': 'androidGradlePluginVersion: 6.7, fileExtension: .aab', 'cd37': 'androidGradlePluginVersion: 6.7, fileExtension: .aab',
}, }),
), ),
)); ));
}); });
......
...@@ -160,10 +160,10 @@ void main() { ...@@ -160,10 +160,10 @@ void main() {
'build', 'build',
'ios', 'ios',
label: 'xcode-bitcode-failure', label: 'xcode-bitcode-failure',
parameters: <String, String>{ parameters: CustomDimensions(
cdKey(CustomDimensions.buildEventCommand): buildCommands.toString(), buildEventCommand: buildCommands.toString(),
cdKey(CustomDimensions.buildEventSettings): buildSettings.toString(), buildEventSettings: buildSettings.toString(),
}, ),
), ),
)); ));
}); });
......
...@@ -74,9 +74,9 @@ void main() { ...@@ -74,9 +74,9 @@ void main() {
expect(usage.events, unorderedEquals(<TestUsageEvent>[ expect(usage.events, unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'), const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'),
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: <String, String>{ TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: CustomDimensions.fromMap(<String, String>{
'cd49': '1', 'cd50': '3', 'cd49': '1', 'cd50': '3',
}), })),
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'language-version', label: '2.12'), const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'language-version', label: '2.12'),
])); ]));
}); });
...@@ -98,9 +98,9 @@ void main() { ...@@ -98,9 +98,9 @@ void main() {
expect(usage.events, unorderedEquals(<TestUsageEvent>[ expect(usage.events, unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'), const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'),
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: <String, String>{ TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: CustomDimensions.fromMap(<String, String>{
'cd49': '1', 'cd50': '3', 'cd49': '1', 'cd50': '3',
}), })),
])); ]));
}); });
...@@ -119,9 +119,9 @@ void main() { ...@@ -119,9 +119,9 @@ void main() {
expect(usage.events, unorderedEquals(<TestUsageEvent>[ expect(usage.events, unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'), const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'runtime-mode', label: 'NullSafetyMode.sound'),
const TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: <String, String>{ TestUsageEvent(NullSafetyAnalysisEvent.kNullSafetyCategory, 'stats', parameters: CustomDimensions.fromMap(<String, String>{
'cd49': '0', 'cd50': '1', 'cd49': '0', 'cd50': '1',
}), })),
])); ]));
}); });
} }
......
...@@ -550,13 +550,12 @@ void main() { ...@@ -550,13 +550,12 @@ void main() {
expect(result.fatal, true); expect(result.fatal, true);
expect(result.code, 1); expect(result.code, 1);
expect((globals.flutterUsage as TestUsage).events, contains( expect((globals.flutterUsage as TestUsage).events, contains(
TestUsageEvent('hot', 'exception', parameters: <String, String>{ TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
cdKey(CustomDimensions.hotEventTargetPlatform): hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
getNameForTargetPlatform(TargetPlatform.android_arm), hotEventSdkName: 'Android',
cdKey(CustomDimensions.hotEventSdkName): 'Android', hotEventEmulator: false,
cdKey(CustomDimensions.hotEventEmulator): 'false', hotEventFullRestart: false,
cdKey(CustomDimensions.hotEventFullRestart): 'false', )),
}),
)); ));
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -623,13 +622,12 @@ void main() { ...@@ -623,13 +622,12 @@ void main() {
expect(result.message, contains('Unable to hot reload application due to an unrecoverable error')); expect(result.message, contains('Unable to hot reload application due to an unrecoverable error'));
expect((globals.flutterUsage as TestUsage).events, contains( expect((globals.flutterUsage as TestUsage).events, contains(
TestUsageEvent('hot', 'reload-barred', parameters: <String, String>{ TestUsageEvent('hot', 'reload-barred', parameters: CustomDimensions(
cdKey(CustomDimensions.hotEventTargetPlatform): hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
getNameForTargetPlatform(TargetPlatform.android_arm), hotEventSdkName: 'Android',
cdKey(CustomDimensions.hotEventSdkName): 'Android', hotEventEmulator: false,
cdKey(CustomDimensions.hotEventEmulator): 'false', hotEventFullRestart: false,
cdKey(CustomDimensions.hotEventFullRestart): 'false', )),
}),
)); ));
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -686,13 +684,12 @@ void main() { ...@@ -686,13 +684,12 @@ void main() {
expect(result.code, 1); expect(result.code, 1);
expect((globals.flutterUsage as TestUsage).events, contains( expect((globals.flutterUsage as TestUsage).events, contains(
TestUsageEvent('hot', 'exception', parameters: <String, String>{ TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
cdKey(CustomDimensions.hotEventTargetPlatform): hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
getNameForTargetPlatform(TargetPlatform.android_arm), hotEventSdkName: 'Android',
cdKey(CustomDimensions.hotEventSdkName): 'Android', hotEventEmulator: false,
cdKey(CustomDimensions.hotEventEmulator): 'false', hotEventFullRestart: false,
cdKey(CustomDimensions.hotEventFullRestart): 'false', )),
}),
)); ));
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -981,10 +978,7 @@ void main() { ...@@ -981,10 +978,7 @@ void main() {
final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first; final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
expect(event.category, 'hot'); expect(event.category, 'hot');
expect(event.parameter, 'reload'); expect(event.parameter, 'reload');
expect(event.parameters, containsPair( expect(event.parameters.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
cdKey(CustomDimensions.hotEventTargetPlatform),
getNameForTargetPlatform(TargetPlatform.android_arm),
));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Usage: () => TestUsage(), Usage: () => TestUsage(),
}), overrides: <Type, Generator>{ }), overrides: <Type, Generator>{
...@@ -1089,9 +1083,7 @@ void main() { ...@@ -1089,9 +1083,7 @@ void main() {
final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first; final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
expect(event.category, 'hot'); expect(event.category, 'hot');
expect(event.parameter, 'reload'); expect(event.parameter, 'reload');
expect(event.parameters, containsPair( expect(event.parameters.fastReassemble, true);
cdKey(CustomDimensions.fastReassemble), 'true',
));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(), FileSystem: () => MemoryFileSystem.test(),
Platform: () => FakePlatform(operatingSystem: 'linux'), Platform: () => FakePlatform(operatingSystem: 'linux'),
...@@ -1157,9 +1149,7 @@ void main() { ...@@ -1157,9 +1149,7 @@ void main() {
final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first; final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
expect(event.category, 'hot'); expect(event.category, 'hot');
expect(event.parameter, 'restart'); expect(event.parameter, 'restart');
expect(event.parameters, containsPair( expect(event.parameters.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
cdKey(CustomDimensions.hotEventTargetPlatform), getNameForTargetPlatform(TargetPlatform.android_arm),
));
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Usage: () => TestUsage(), Usage: () => TestUsage(),
...@@ -1395,13 +1385,12 @@ void main() { ...@@ -1395,13 +1385,12 @@ void main() {
expect(result.code, 1); expect(result.code, 1);
expect((globals.flutterUsage as TestUsage).events, contains( expect((globals.flutterUsage as TestUsage).events, contains(
TestUsageEvent('hot', 'exception', parameters: <String, String>{ TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
cdKey(CustomDimensions.hotEventTargetPlatform): hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
getNameForTargetPlatform(TargetPlatform.android_arm), hotEventSdkName: 'Android',
cdKey(CustomDimensions.hotEventSdkName): 'Android', hotEventEmulator: false,
cdKey(CustomDimensions.hotEventEmulator): 'false', hotEventFullRestart: true,
cdKey(CustomDimensions.hotEventFullRestart): 'true', )),
}),
)); ));
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
......
...@@ -580,8 +580,8 @@ void main() { ...@@ -580,8 +580,8 @@ void main() {
verify(mockResidentCompiler.accept()).called(2); verify(mockResidentCompiler.accept()).called(2);
// ensure that analytics are sent. // ensure that analytics are sent.
expect(testUsage.events, const <TestUsageEvent>[ expect(testUsage.events, <TestUsageEvent>[
TestUsageEvent('hot', 'restart', parameters: <String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'}), TestUsageEvent('hot', 'restart', parameters: CustomDimensions.fromMap(<String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'})),
]); ]);
expect(testUsage.timings, const <TestTimingEvent>[ expect(testUsage.timings, const <TestTimingEvent>[
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero), TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
...@@ -658,8 +658,8 @@ void main() { ...@@ -658,8 +658,8 @@ void main() {
verify(mockResidentCompiler.accept()).called(2); verify(mockResidentCompiler.accept()).called(2);
// ensure that analytics are sent. // ensure that analytics are sent.
expect(testUsage.events, const <TestUsageEvent>[ expect(testUsage.events, <TestUsageEvent>[
TestUsageEvent('hot', 'restart', parameters: <String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'}), TestUsageEvent('hot', 'restart', parameters: CustomDimensions.fromMap(<String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'})),
]); ]);
expect(testUsage.timings, const <TestTimingEvent>[ expect(testUsage.timings, const <TestTimingEvent>[
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero), TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
......
...@@ -483,12 +483,12 @@ void main() { ...@@ -483,12 +483,12 @@ void main() {
'runtime-mode', 'runtime-mode',
label: 'NullSafetyMode.sound', label: 'NullSafetyMode.sound',
), ),
const TestUsageEvent( TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory, NullSafetyAnalysisEvent.kNullSafetyCategory,
'stats', 'stats',
parameters: <String, String>{ parameters: CustomDimensions.fromMap(<String, String>{
'cd49': '1', 'cd50': '1', 'cd49': '1', 'cd50': '1',
}, }),
), ),
const TestUsageEvent( const TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory, NullSafetyAnalysisEvent.kNullSafetyCategory,
......
...@@ -282,7 +282,7 @@ class CrashingUsage implements Usage { ...@@ -282,7 +282,7 @@ class CrashingUsage implements Usage {
String get clientId => _impl.clientId; String get clientId => _impl.clientId;
@override @override
void sendCommand(String command, {Map<String, String> parameters}) => void sendCommand(String command, {CustomDimensions parameters}) =>
_impl.sendCommand(command, parameters: parameters); _impl.sendCommand(command, parameters: parameters);
@override @override
...@@ -291,7 +291,7 @@ class CrashingUsage implements Usage { ...@@ -291,7 +291,7 @@ class CrashingUsage implements Usage {
String parameter, { String parameter, {
String label, String label,
int value, int value,
Map<String, String> parameters, CustomDimensions parameters,
}) => _impl.sendEvent( }) => _impl.sendEvent(
category, category,
parameter, parameter,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment