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 {
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
void printNoConnectedDevices() {
super.printNoConnectedDevices();
......@@ -264,7 +274,7 @@ class RunCommand extends RunCommandBase {
throwToolExit(null, exitCode: result);
return new FlutterCommandResult(
ExitStatus.success,
analyticsParameters: <String>['daemon'],
timingLabelParts: <String>['daemon'],
endTimeOverride: appStartedTime,
);
}
......@@ -335,7 +345,7 @@ class RunCommand extends RunCommandBase {
throwToolExit(null, exitCode: result);
return new FlutterCommandResult(
ExitStatus.success,
analyticsParameters: <String>[
timingLabelParts: <String>[
hotMode ? 'hot' : 'cold',
getModeName(getBuildMode()),
devices.length == 1
......
......@@ -36,16 +36,16 @@ enum ExitStatus {
class FlutterCommandResult {
const FlutterCommandResult(
this.exitStatus, {
this.analyticsParameters,
this.timingLabelParts,
this.endTimeOverride,
});
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
/// Do not add PII.
final List<String> analyticsParameters;
final List<String> timingLabelParts;
/// Optional epoch time when the command's non-interactive wait time is
/// complete during the command's execution. Use to measure user perceivable
......@@ -138,6 +138,9 @@ abstract class FlutterCommand extends Command<Null> {
/// tracking of the command.
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.
///
/// Rather than overriding this method, subclasses should override
......@@ -164,8 +167,8 @@ abstract class FlutterCommand extends Command<Null> {
final List<String> labels = <String>[];
if (commandResult?.exitStatus != null)
labels.add(getEnumName(commandResult.exitStatus));
if (commandResult?.analyticsParameters?.isNotEmpty ?? false)
labels.addAll(commandResult.analyticsParameters);
if (commandResult?.timingLabelParts?.isNotEmpty ?? false)
labels.addAll(commandResult.timingLabelParts);
final String label = labels
.where((String label) => !isBlank(label))
......@@ -205,8 +208,12 @@ abstract class FlutterCommand extends Command<Null> {
setupApplicationPackages();
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();
}
......
......@@ -75,14 +75,23 @@ class Usage {
/// reports coming from the same computer.
String get clientId => _analytics.clientId;
void sendCommand(String command) {
if (!suppressAnalytics)
_analytics.sendScreenView(command);
void sendCommand(String command, { Map<String, String> parameters }) {
if (suppressAnalytics)
return;
parameters ??= const <String, String>{};
_analytics.sendScreenView(command, parameters: parameters);
}
void sendEvent(String category, String parameter) {
if (!suppressAnalytics)
_analytics.sendEvent(category, parameter);
void sendEvent(String category, String parameter,
{ Map<String, String> parameters }) {
if (suppressAnalytics)
return;
parameters ??= const <String, String>{};
_analytics.sendEvent(category, parameter, parameters: parameters);
}
void sendTiming(
......
......@@ -24,7 +24,7 @@ dependencies:
process: 2.0.3
quiver: ^0.24.0
stack_trace: ^1.4.0
usage: ^3.1.1
usage: ^3.2.0+1
vm_service_client: '0.2.2+4'
web_socket_channel: ^1.0.4
xml: ^2.4.1
......
......@@ -91,7 +91,7 @@ void main() {
final FlutterCommandResult commandResult = new FlutterCommandResult(
ExitStatus.success,
// nulls should be cleaned up.
analyticsParameters: <String> ['blah1', 'blah2', null, 'blah3'],
timingLabelParts: <String> ['blah1', 'blah2', null, 'blah3'],
endTimeOverride: new DateTime.fromMillisecondsSinceEpoch(1500)
);
......
......@@ -218,10 +218,10 @@ class MockUsage implements Usage {
String get clientId => '00000000-0000-4000-0000-000000000000';
@override
void sendCommand(String command) { }
void sendCommand(String command, { Map<String, String> parameters }) { }
@override
void sendEvent(String category, String parameter) { }
void sendEvent(String category, String parameter, { Map<String, String> parameters }) { }
@override
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