add google analytics to flutter_tools (#3523)

* add google analytics

* send in the run target type

* track device type targets

* use the real GA code

* review comments

* rev to usage 2.0

* rev to 2.2.0 of usage; add tests

* review comments
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 432682e6..1ebc038 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -15,6 +15,7 @@
 import '../globals.dart';
 import '../package_map.dart';
 import '../toolchain.dart';
+import '../usage.dart';
 import 'flutter_command_runner.dart';
 
 typedef bool Validator();
@@ -94,13 +95,19 @@
     applicationPackages ??= new ApplicationPackageStore();
   }
 
+  /// The path to send to Google Analytics. Return `null` here to disable
+  /// tracking of the command.
+  String get usagePath => name;
+
   @override
   Future<int> run() {
     Stopwatch stopwatch = new Stopwatch()..start();
+    UsageTimer analyticsTimer = usagePath == null ? null : flutterUsage.startTimer(name);
 
     return _run().then((int exitCode) {
       int ms = stopwatch.elapsedMilliseconds;
       printTrace("'flutter $name' took ${ms}ms; exiting with code $exitCode.");
+      analyticsTimer?.finish();
       return exitCode;
     });
   }
@@ -160,6 +167,10 @@
     _setupToolchain();
     _setupApplicationPackages();
 
+    String commandPath = usagePath;
+    if (commandPath != null)
+      flutterUsage.sendCommand(usagePath);
+
     return await runInProject();
   }
 
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index a050656..955eee1 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -84,13 +84,15 @@
     argParser.addOption('host-debug-build-path',
         hide: !verboseHelp,
         help:
-            'Path to your host Debug out directory (i.e. the one that runs on your workstation, not a device), if you are building Flutter locally.\n'
+            'Path to your host Debug out directory (i.e. the one that runs on your workstation, not a device),\n'
+            'if you are building Flutter locally.\n'
             'This path is relative to --engine-src-path. Not normally required.',
         defaultsTo: 'out/Debug/');
     argParser.addOption('host-release-build-path',
         hide: !verboseHelp,
         help:
-            'Path to your host Release out directory (i.e. the one that runs on your workstation, not a device), if you are building Flutter locally.\n'
+            'Path to your host Release out directory (i.e. the one that runs on your workstation, not a device),\n'
+            'if you are building Flutter locally.\n'
             'This path is relative to --engine-src-path. Not normally required.',
         defaultsTo: 'out/Release/');
 
@@ -232,6 +234,7 @@
     }
 
     if (globalResults['version']) {
+      flutterUsage.sendCommand('version');
       printStatus(FlutterVersion.getVersion(ArtifactStore.flutterRoot).toString());
       return new Future<int>.value(0);
     }
diff --git a/packages/flutter_tools/lib/src/runner/version.dart b/packages/flutter_tools/lib/src/runner/version.dart
index eb0a53b..dba2f7e 100644
--- a/packages/flutter_tools/lib/src/runner/version.dart
+++ b/packages/flutter_tools/lib/src/runner/version.dart
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+
 import '../artifacts.dart';
 import '../base/process.dart';
 
@@ -54,4 +56,21 @@
   static FlutterVersion getVersion([String flutterRoot]) {
     return new FlutterVersion(flutterRoot != null ? flutterRoot : ArtifactStore.flutterRoot);
   }
+
+  static String getVersionString() {
+    final String cwd = ArtifactStore.flutterRoot;
+
+    String commit = _runSync('git', <String>['rev-parse', 'HEAD'], cwd);
+    if (commit.length > 8)
+      commit = commit.substring(0, 8);
+
+    String branch = _runSync('git', <String>['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
+
+    return '$commit/$branch';
+  }
+}
+
+String _runSync(String executable, List<String> arguments, String cwd) {
+  ProcessResult results = Process.runSync(executable, arguments, workingDirectory: cwd);
+  return results.exitCode == 0 ? results.stdout.trim() : '';
 }