Commit 834fbcb8 authored by Seth Ladd's avatar Seth Ladd Committed by GitHub

Run target analytics (#10902)

* report run target and if it is an emulator

* don't print debug

* rename parameter, remove unused variable

* fix test

* fix comment

* tweak from review, and fix analyzer error

* send custom parameters for the event, not the session

* fix mock

* use the +1 for usage
parent 48915069
...@@ -173,6 +173,16 @@ class RunCommand extends RunCommandBase { ...@@ -173,6 +173,16 @@ class RunCommand extends RunCommandBase {
return '$command/${getNameForTargetPlatform(await devices[0].targetPlatform)}'; return '$command/${getNameForTargetPlatform(await devices[0].targetPlatform)}';
} }
@override
Future<Map<String, String>> get usageValues async {
final bool isEmulator = await devices[0].isLocalEmulator;
final String deviceType = devices.length == 1
? getNameForTargetPlatform(await devices[0].targetPlatform)
: 'multiple';
return <String, String>{ 'cd3': '$isEmulator', 'cd4': deviceType };
}
@override @override
void printNoConnectedDevices() { void printNoConnectedDevices() {
super.printNoConnectedDevices(); super.printNoConnectedDevices();
...@@ -264,7 +274,7 @@ class RunCommand extends RunCommandBase { ...@@ -264,7 +274,7 @@ class RunCommand extends RunCommandBase {
throwToolExit(null, exitCode: result); throwToolExit(null, exitCode: result);
return new FlutterCommandResult( return new FlutterCommandResult(
ExitStatus.success, ExitStatus.success,
analyticsParameters: <String>['daemon'], timingLabelParts: <String>['daemon'],
endTimeOverride: appStartedTime, endTimeOverride: appStartedTime,
); );
} }
...@@ -335,7 +345,7 @@ class RunCommand extends RunCommandBase { ...@@ -335,7 +345,7 @@ class RunCommand extends RunCommandBase {
throwToolExit(null, exitCode: result); throwToolExit(null, exitCode: result);
return new FlutterCommandResult( return new FlutterCommandResult(
ExitStatus.success, ExitStatus.success,
analyticsParameters: <String>[ timingLabelParts: <String>[
hotMode ? 'hot' : 'cold', hotMode ? 'hot' : 'cold',
getModeName(getBuildMode()), getModeName(getBuildMode()),
devices.length == 1 devices.length == 1
......
...@@ -36,16 +36,16 @@ enum ExitStatus { ...@@ -36,16 +36,16 @@ enum ExitStatus {
class FlutterCommandResult { class FlutterCommandResult {
const FlutterCommandResult( const FlutterCommandResult(
this.exitStatus, { this.exitStatus, {
this.analyticsParameters, this.timingLabelParts,
this.endTimeOverride, this.endTimeOverride,
}); });
final ExitStatus exitStatus; final ExitStatus exitStatus;
/// Optional dimension data that can be appended to the timing event. /// Optional data that can be appended to the timing event.
/// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#timingLabel /// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#timingLabel
/// Do not add PII. /// Do not add PII.
final List<String> analyticsParameters; final List<String> timingLabelParts;
/// Optional epoch time when the command's non-interactive wait time is /// Optional epoch time when the command's non-interactive wait time is
/// complete during the command's execution. Use to measure user perceivable /// complete during the command's execution. Use to measure user perceivable
...@@ -138,6 +138,9 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -138,6 +138,9 @@ abstract class FlutterCommand extends Command<Null> {
/// tracking of the command. /// tracking of the command.
Future<String> get usagePath async => name; Future<String> get usagePath async => name;
/// Additional usage values to be sent with the usage ping.
Future<Map<String, String>> get usageValues async => const <String, String>{};
/// Runs this command. /// Runs this command.
/// ///
/// Rather than overriding this method, subclasses should override /// Rather than overriding this method, subclasses should override
...@@ -164,8 +167,8 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -164,8 +167,8 @@ abstract class FlutterCommand extends Command<Null> {
final List<String> labels = <String>[]; final List<String> labels = <String>[];
if (commandResult?.exitStatus != null) if (commandResult?.exitStatus != null)
labels.add(getEnumName(commandResult.exitStatus)); labels.add(getEnumName(commandResult.exitStatus));
if (commandResult?.analyticsParameters?.isNotEmpty ?? false) if (commandResult?.timingLabelParts?.isNotEmpty ?? false)
labels.addAll(commandResult.analyticsParameters); labels.addAll(commandResult.timingLabelParts);
final String label = labels final String label = labels
.where((String label) => !isBlank(label)) .where((String label) => !isBlank(label))
...@@ -205,8 +208,12 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -205,8 +208,12 @@ abstract class FlutterCommand extends Command<Null> {
setupApplicationPackages(); setupApplicationPackages();
final String commandPath = await usagePath; final String commandPath = await usagePath;
if (commandPath != null)
flutterUsage.sendCommand(commandPath); if (commandPath != null) {
final Map<String, String> additionalUsageValues = await usageValues;
flutterUsage.sendCommand(commandPath, parameters: additionalUsageValues);
}
return await runCommand(); return await runCommand();
} }
......
...@@ -75,14 +75,23 @@ class Usage { ...@@ -75,14 +75,23 @@ class Usage {
/// reports coming from the same computer. /// reports coming from the same computer.
String get clientId => _analytics.clientId; String get clientId => _analytics.clientId;
void sendCommand(String command) { void sendCommand(String command, { Map<String, String> parameters }) {
if (!suppressAnalytics) if (suppressAnalytics)
_analytics.sendScreenView(command); return;
parameters ??= const <String, String>{};
_analytics.sendScreenView(command, parameters: parameters);
} }
void sendEvent(String category, String parameter) { void sendEvent(String category, String parameter,
if (!suppressAnalytics) { Map<String, String> parameters }) {
_analytics.sendEvent(category, parameter); if (suppressAnalytics)
return;
parameters ??= const <String, String>{};
_analytics.sendEvent(category, parameter, parameters: parameters);
} }
void sendTiming( void sendTiming(
......
...@@ -24,7 +24,7 @@ dependencies: ...@@ -24,7 +24,7 @@ dependencies:
process: 2.0.3 process: 2.0.3
quiver: ^0.24.0 quiver: ^0.24.0
stack_trace: ^1.4.0 stack_trace: ^1.4.0
usage: ^3.1.1 usage: ^3.2.0+1
vm_service_client: '0.2.2+4' vm_service_client: '0.2.2+4'
web_socket_channel: ^1.0.4 web_socket_channel: ^1.0.4
xml: ^2.4.1 xml: ^2.4.1
......
...@@ -91,7 +91,7 @@ void main() { ...@@ -91,7 +91,7 @@ void main() {
final FlutterCommandResult commandResult = new FlutterCommandResult( final FlutterCommandResult commandResult = new FlutterCommandResult(
ExitStatus.success, ExitStatus.success,
// nulls should be cleaned up. // nulls should be cleaned up.
analyticsParameters: <String> ['blah1', 'blah2', null, 'blah3'], timingLabelParts: <String> ['blah1', 'blah2', null, 'blah3'],
endTimeOverride: new DateTime.fromMillisecondsSinceEpoch(1500) endTimeOverride: new DateTime.fromMillisecondsSinceEpoch(1500)
); );
......
...@@ -218,10 +218,10 @@ class MockUsage implements Usage { ...@@ -218,10 +218,10 @@ class MockUsage implements Usage {
String get clientId => '00000000-0000-4000-0000-000000000000'; String get clientId => '00000000-0000-4000-0000-000000000000';
@override @override
void sendCommand(String command) { } void sendCommand(String command, { Map<String, String> parameters }) { }
@override @override
void sendEvent(String category, String parameter) { } void sendEvent(String category, String parameter, { Map<String, String> parameters }) { }
@override @override
void sendTiming(String category, String variableName, Duration duration, { String label }) { } void sendTiming(String category, String variableName, Duration duration, { String label }) { }
......
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