Read information about AVDs from config.ini
diff --git a/packages/flutter_tools/lib/src/android/android_emulator.dart b/packages/flutter_tools/lib/src/android/android_emulator.dart
index 3602aa0..30dd0fc 100644
--- a/packages/flutter_tools/lib/src/android/android_emulator.dart
+++ b/packages/flutter_tools/lib/src/android/android_emulator.dart
@@ -8,6 +8,7 @@
 
 import '../android/android_sdk.dart';
 import '../android/android_workflow.dart';
+import '../base/file_system.dart';
 import '../base/process.dart';
 import '../emulator.dart';
 import 'android_sdk.dart';
@@ -24,12 +25,19 @@
 }
 
 class AndroidEmulator extends Emulator {
-  AndroidEmulator(
-    String id
-  ) : super(id);
+  AndroidEmulator(String id, [this._properties])
+  : super(id, _properties != null && _properties.isNotEmpty);
+
+  Map<String, String> _properties;
 
   @override
-  String get name => id;
+  String get name => _properties['hw.device.name'];
+
+  @override
+  String get manufacturer => _properties['hw.device.manufacturer'];
+
+  @override
+  String get label => _properties['avd.ini.displayname'];
 
   // @override
   // Future<bool> launch() async {
@@ -41,20 +49,57 @@
 /// Return the list of available emulator AVDs.
 List<AndroidEmulator> getEmulatorAvds() {
   final String emulatorPath = getEmulatorPath(androidSdk);
-  if (emulatorPath == null)
+  if (emulatorPath == null) {
     return <AndroidEmulator>[];
-  final String text = runSync(<String>[emulatorPath, '-list-avds']);
+  }
+  
+  final String listAvdsOutput = runSync(<String>[emulatorPath, '-list-avds']);
+
   final List<AndroidEmulator> emulators = <AndroidEmulator>[];
-  parseEmulatorAvdOutput(text, emulators);
+  extractEmulatorAvdInfo(listAvdsOutput, emulators);
   return emulators;
 }
 
 /// Parse the given `emulator -list-avds` output in [text], and fill out the given list
-/// of emulators.
-@visibleForTesting
-void parseEmulatorAvdOutput(String text,
-  List<AndroidEmulator> emulators) {
-  for (String line in text.trim().split('\n')) {
-    emulators.add(new AndroidEmulator(line));
+/// of emulators by reading information from the relevant ini files.
+void extractEmulatorAvdInfo(String text, List<AndroidEmulator> emulators) {
+  for (String id in text.trim().split('\n')) {
+    emulators.add(_createEmulator(id));
   }
 }
+
+AndroidEmulator _createEmulator(String id) {
+  id = id.trim();
+  final File iniFile = fs.file(fs.path.join(getAvdPath(), '$id.ini'));
+  final Map<String, String> ini = _parseIniLines(iniFile.readAsLinesSync());
+
+  if (ini['path'] != null) {
+    final File configFile = fs.file(fs.path.join(ini['path'], 'config.ini'));
+    if (configFile.existsSync()) {
+      final Map<String, String> properties = _parseIniLines(configFile.readAsLinesSync());
+      return new AndroidEmulator(id, properties);
+    }
+  }
+
+  return new AndroidEmulator(id);
+}
+
+// TODO: Tests
+@visibleForTesting
+Map<String, String> _parseIniLines(List<String> contents) {
+  final Map<String, String> results = <String, String>{};
+
+  final Iterable<List<String>> properties = contents
+      .map((String l) => l.trim())
+      .where((String l) =>
+          l != '' && !l.startsWith('#')) // Strip blank lines/comments
+      .where((String l) =>
+          l.contains('=')) // Discard anything that isn't simple name=value
+      .map((String l) => l.split('=')); // Split into name/value
+
+  for (List<String> property in properties) {
+    results[property[0].trim()] = property[1].trim();
+  }
+
+  return results;
+}
diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart
index 1875c48..bc10b95 100644
--- a/packages/flutter_tools/lib/src/android/android_sdk.dart
+++ b/packages/flutter_tools/lib/src/android/android_sdk.dart
@@ -59,9 +59,9 @@
   }
 }
 
-/// Locate ADB. Prefer to use one from an Android SDK, if we can locate that.
-/// This should be used over accessing androidSdk.adbPath directly because it
-/// will work for those users who have Android Platform Tools installed but
+/// Locate 'emulator'. Prefer to use one from an Android SDK, if we can locate that.
+/// This should be used over accessing androidSdk.emulatorPath directly because it
+/// will work for those users who have Android Tools installed but
 /// not the full SDK.
 String getEmulatorPath([AndroidSdk existingSdk]) {
   if (existingSdk?.emulatorPath != null)
@@ -76,6 +76,18 @@
   }
 }
 
+/// Locate the path for storing AVD emulator images. Returns null if none found.
+String getAvdPath() {
+  final List<String> searchPaths = <String>[
+    platform.environment['ANDROID_AVD_HOME'],
+    fs.path.join(platform.environment['HOME'], '.android', 'avd'),
+  ];
+  return searchPaths.where((String p) => p != null).firstWhere(
+    (String p) => fs.directory(p).existsSync(),
+    orElse: () => null,
+  );
+}
+
 class AndroidSdk {
   AndroidSdk(this.directory, [this.ndkDirectory, this.ndkCompiler,
       this.ndkCompilerArgs]) {
diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart
index db40d65..737eb1f 100644
--- a/packages/flutter_tools/lib/src/android/android_workflow.dart
+++ b/packages/flutter_tools/lib/src/android/android_workflow.dart
@@ -43,7 +43,7 @@
   bool get canLaunchDevices => androidSdk != null && androidSdk.validateSdkWellFormed().isEmpty;
 
   @override
-  bool get canListEmulators => getEmulatorPath(androidSdk) != null;
+  bool get canListEmulators => getEmulatorPath(androidSdk) != null && getAvdPath() != null;
 
   static const String _kJdkDownload = 'https://www.oracle.com/technetwork/java/javase/downloads/';
 
diff --git a/packages/flutter_tools/lib/src/emulator.dart b/packages/flutter_tools/lib/src/emulator.dart
index 57c647a..af243ed 100644
--- a/packages/flutter_tools/lib/src/emulator.dart
+++ b/packages/flutter_tools/lib/src/emulator.dart
@@ -115,11 +115,13 @@
 }
 
 abstract class Emulator {
-  Emulator(this.id);
+  Emulator(this.id, this.hasConfig);
 
   final String id;
-
-  String get name => id;
+  final bool hasConfig;
+  String get name;
+  String get manufacturer;
+  String get label;
 
   @override
   int get hashCode => id.hashCode;
@@ -145,6 +147,8 @@
     for (Emulator emulator in emulators) {
       table.add(<String>[
         emulator.name,
+        emulator.manufacturer,
+        emulator.label,
         emulator.id,
       ]);
     }